<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Chapter 21 InnoDB Cluster</title>
<link rel="stylesheet" href="mvl.css" type="text/css" />
<meta name="generator" content="DocBook XSL Stylesheets + chunker.py v1.9.2" />
<link rel="start" href="index.html" title="{book-title}" />
<link rel="up" href="" title="" />
<link rel="prev" href="document-store.html" title="Chapter 20 Using MySQL as a Document Store" />
<link rel="next" href="mysql-cluster.html" title="Chapter 22 MySQL NDB Cluster 8.0" />
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<div class="navheader">
<table width="100%" summary="Navigation header">
<tr>
<th colspan="3" align="center">Chapter 21 InnoDB Cluster</th>
</tr>
<tr>
<td width="20%" align="left"><a accesskey="p" href="document-store.html">Prev</a> </td>
<th width="60%" align="center"></th>
<td width="20%" align="right"> <a accesskey="n" href="mysql-cluster.html">Next</a></td>
</tr>
</table>
<hr>
</div>
<div class="chapter">
<div class="titlepage">
<div>
<div>
<h1 class="title"><a name="mysql-innodb-cluster-userguide"></a>Chapter 21 InnoDB Cluster</h1>

</div>

</div>

</div>
<div class="toc">
<p><b>Table of Contents</b></p><dl class="toc"><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-introduction">21.1 Introducing InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-creating">21.2 Creating an InnoDB Cluster</a></span></dt><dd><dl><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-deployment-methods">21.2.1 Deployment Scenarios</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-requirements">21.2.2 InnoDB Cluster Requirements</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-methods-installing">21.2.3 Methods of Installing</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment">21.2.4 Production Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-clone-deployment">21.2.5 Using MySQL Clone with InnoDB cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment">21.2.6 Sandbox Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-from-group-replication">21.2.7 Adopting a Group Replication Deployment</a></span></dt></dl></dd><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade">21.3 Upgrading an InnoDB cluster</a></span></dt><dd><dl><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade-rolling">21.3.1 Rolling Upgrades</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade-metadata">21.3.2 Upgrading InnoDB cluster Metadata</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade-troubleshoot">21.3.3 Troubleshooting InnoDB cluster Upgrades</a></span></dt></dl></dd><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-using-router">21.4 Using MySQL Router with InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-working-with-cluster">21.5 Working with InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-replicasets">21.6 InnoDB ReplicaSet</a></span></dt><dd><dl><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-replicasets-introduction">21.6.1 InnoDB ReplicaSet Introduction</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#deploying-innodb-replicasets">21.6.2 Deploying InnoDB ReplicaSet</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#adding-replicaset-instances">21.6.3 Adding Instances to a Replica Set</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#replicaset-adopting">21.6.4 Adopting an Existing Replication Set Up</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#working-with-replicasets">21.6.5 Working with InnoDB ReplicaSet</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#replicasets-working-with-router">21.6.6 Using Replica Sets with MySQL Router</a></span></dt></dl></dd><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-limitations">21.7 Known Limitations</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444251720816"></a><p>
    This chapter covers MySQL InnoDB cluster, which combines MySQL
    technologies to enable you to create highly available clusters of
    MySQL server instances.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-introduction"></a>21.1 Introducing InnoDB Cluster</h2>
</div>
</div>
</div>
<a class="indexterm" name="idm46444251718128"></a><a class="indexterm" name="idm46444251716640"></a><a class="indexterm" name="idm46444251715152"></a><a class="indexterm" name="idm46444251713664"></a><p>
      MySQL InnoDB cluster provides a complete high availability
      solution for MySQL.
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/" target="_top">MySQL Shell</a> includes
      AdminAPI which enables you to easily configure and administer a
      group of at least three MySQL server instances to function as an
      InnoDB cluster. Each MySQL server instance runs
      MySQL Group Replication, which provides the mechanism to
      replicate data within InnoDB clusters, with built-in failover.
      AdminAPI removes the need to work directly with Group
      Replication in InnoDB clusters, but for more information see
      <a class="xref" href="group-replication.html" title="Chapter 18 Group Replication">Chapter 18, <i>Group Replication</i></a> which explains the details.
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/" target="_top">MySQL Router</a> can automatically
      configure itself based on the cluster you deploy, connecting
      client applications transparently to the server instances. In the
      event of an unexpected failure of a server instance the cluster
      reconfigures automatically. In the default single-primary mode, an
      InnoDB cluster has a single read-write server instance - the
      primary. Multiple secondary server instances are replicas of the
      primary. If the primary fails, a secondary is automatically
      promoted to the role of primary. MySQL Router detects this and
      forwards client applications to the new primary. Advanced users
      can also configure a cluster to have multiple-primaries.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
        InnoDB cluster does not provide support for MySQL NDB Cluster.
        NDB Cluster depends on the <a class="link" href="mysql-cluster.html" title="Chapter 22 MySQL NDB Cluster 8.0"><code class="literal">NDB</code></a> storage
        engine as well as a number of programs specific to NDB Cluster which
        are not furnished with MySQL Server 8.0;
        <code class="literal">NDB</code> is available only as part of the MySQL
        NDB Cluster distribution. In addition, the MySQL server binary
        (<a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>) that is supplied with MySQL Server
        8.0 cannot be used with NDB Cluster. For more
        information about MySQL NDB Cluster, see
        <a class="xref" href="mysql-cluster.html" title="Chapter 22 MySQL NDB Cluster 8.0">Chapter 22, <i>MySQL NDB Cluster 8.0</i></a>.
        <a class="xref" href="mysql-cluster.html#mysql-cluster-compared" title="22.1.6 MySQL Server Using InnoDB Compared with NDB Cluster">Section 22.1.6, “MySQL Server Using InnoDB Compared with NDB Cluster”</a>, provides information
        about the differences between the <code class="literal">InnoDB</code> and
        <code class="literal">NDB</code> storage engines.
</p>
</div>
<p>
      The following diagram shows an overview of how these technologies
      work together:
</p>
<div class="figure">
<a name="innodb-cluster-overview-image"></a><p class="title"><b>Figure 21.1 InnoDB cluster overview</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/innodb_cluster_overview.png" width="600" height="753" alt="Three MySQL servers are grouped together as a high availability cluster. One of the servers is the read/write primary instance, and the other two are read-only secondary instances. Group Replication is used to replicate data from the primary instance to the secondary instances. MySQL Router connects client applications (in this example, a MySQL Connector) to the primary instance.">
</div>

</div>

</div>
<br class="figure-break">
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h3 class="title"><a name="admin-api"></a>Using AdminAPI</h3>

</div>

</div>

</div>
<p>
        MySQL Shell includes the AdminAPI, which is accessed through
        the <code class="literal">dba</code> global variable and its associated
        methods. The <code class="literal">dba</code> variable's methods enable
        you to deploy, configure, and administer InnoDB clusters. For
        example, use the <code class="literal">dba.createCluster()</code> method
        to create an InnoDB cluster.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          MySQL Shell enables you to connect to servers over a socket
          connection, but AdminAPI requires TCP connections to a
          server instance. Socket based connections are not supported in
          AdminAPI.
</p>
</div>
<p>
        MySQL Shell provides online help for the AdminAPI. To list
        all available <code class="literal">dba</code> commands, use the
        <code class="literal">dba.help()</code> method. For online help on a
        specific method, use the general format
        <code class="literal">object.help('methodname')</code>. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>dba.help('getCluster')</code></strong>

Retrieves a cluster from the Metadata Store.

SYNTAX

  dba.getCluster([name][, options])

WHERE

  name: Parameter to specify the name of the cluster to be returned.
  options: Dictionary with additional options.

RETURNS

  The cluster object identified by the given name or the default cluster.

DESCRIPTION

If name is not specified or is null, the default cluster will be returned.

If name is specified, and no cluster with the indicated name is found, an error
will be raised.

The options dictionary accepts the connectToPrimary option,which defaults to
true and indicates the shell to automatically connect to the primary member of
the cluster.

EXCEPTIONS

  MetadataError in the following scenarios:

   - If the Metadata is inaccessible.
   - If the Metadata update operation failed.

  ArgumentError in the following scenarios:

   - If the Cluster name is empty.
   - If the Cluster name is invalid.
   - If the Cluster does not exist.

  RuntimeError in the following scenarios:

   - If the current connection cannot be used for Group Replication.
</pre><p>
        MySQL Shell can optionally log the SQL statements used by
        AdminAPI operations (with the exception of sandbox
        operations), and can also display them in the terminal as they
        are executed. To configure MySQL Shell to do this, see
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-application-log-adminapi.html" target="_top">Logging AdminAPI Operations</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="specifying-instances"></a>Specifying Instances</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444251679712"></a><p>
        One of the core concepts of administering InnoDB cluster is
        understanding connections to the MySQL instances which make up
        your cluster. The requirements for connections to the instances
        when administering your InnoDB cluster, and for the
        connections between the instances themselves, are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            only TCP/IP connections are supported, using Unix sockets or
            named pipes is not supported. InnoDB cluster is intended
            to be used in a local area network, running a cluster of
            instances connected over a wide area network is not
            recommended.
          </p></li><li class="listitem"><p>
            only MySQL Classic protocol connections are supported,
            X Protocol is not supported.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
              Your applications can use X Protocol, this requirement is
              for AdminAPI.
</p>
</div>
</li></ul>
</div>
<p>
        MySQL Shell enables you to work with various APIs, and supports
        specifying connections as explained in
        <a class="xref" href="programs.html#connecting-using-uri-or-key-value-pairs" title="4.2.5 Connecting to the Server Using URI-Like Strings or Key-Value Pairs">Section 4.2.5, “Connecting to the Server Using URI-Like Strings or Key-Value Pairs”</a>. The
        <a class="xref" href="programs.html#connection-parameters-additional" title="Additional Connection parameters">Additional Connection parameters</a> are not
        supported by InnoDB cluster. You can specify connections using
        either URI-type strings, or key-value pairs. This documentation
        demonstrates AdminAPI using URI-type connection strings. For
        example, to connect as the user
        <em class="replaceable"><code>myuser</code></em> to the MySQL server instance
        at <em class="replaceable"><code>www.example.com</code></em>, on port
        <em class="replaceable"><code>3306</code></em> use the connection string:
      </p><pre class="programlisting">myuser@www.example.com:3306</pre><p>
        To use this connection string with an AdminAPI operation such
        as <code class="literal">dba.configureInstance()</code>, you need to
        ensure the connection string is interpreted as a string, for
        example by surrounding the connection string with either single
        (') or double (") quote marks. If you are using the JavaScript
        implementation of AdminAPI issue:
      </p><pre class="programlisting">MySQL JS &gt; dba.configureInstance('<em class="replaceable"><code>myuser</code></em>@<em class="replaceable"><code>www.example.com</code></em>:<em class="replaceable"><code>3306</code></em>')</pre><p>
        Assuming you are running MySQL Shell in the default interactive
        mode, you are prompted for your password. AdminAPI supports
        MySQL Shell's
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-pluggable-password-store.html" target="_top">Pluggable Password Store</a>, and once
        you store the password you used to connect to the instance you
        are no longer prompted for it.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-creating"></a>21.2 Creating an InnoDB Cluster</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-deployment-methods">21.2.1 Deployment Scenarios</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-requirements">21.2.2 InnoDB Cluster Requirements</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-methods-installing">21.2.3 Methods of Installing</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment">21.2.4 Production Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-clone-deployment">21.2.5 Using MySQL Clone with InnoDB cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment">21.2.6 Sandbox Deployment of InnoDB Cluster</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-from-group-replication">21.2.7 Adopting a Group Replication Deployment</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444251663040"></a><p>
      This section explains the different ways you can create an
      InnoDB cluster, the requirements for server instances and the
      software you need to install to deploy a cluster.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-deployment-methods"></a>21.2.1 Deployment Scenarios</h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444251659792"></a><p>
        InnoDB cluster supports the following deployment scenarios:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <span class="emphasis"><em>Production deployment:</em></span> if you want to
            use InnoDB cluster in a full production environment you
            need to configure the required number of machines and then
            deploy your server instances to the machines. A production
            deployment enables you to exploit the high availability
            features of InnoDB cluster to their full potential. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment" title="21.2.4 Production Deployment of InnoDB Cluster">Section 21.2.4, “Production Deployment of InnoDB Cluster”</a>
            for instructions.
          </p></li><li class="listitem"><p>
            <span class="emphasis"><em>Sandbox deployment:</em></span> if you want to test
            out InnoDB cluster before committing to a full production
            deployment, the provided sandbox feature enables you to
            quickly set up a cluster on your local machine. Sandbox
            server instances are created with the required configuration
            and you can experiment with InnoDB cluster to become
            familiar with the technologies employed. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment" title="21.2.6 Sandbox Deployment of InnoDB Cluster">Section 21.2.6, “Sandbox Deployment of InnoDB Cluster”</a>
            for instructions.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
              A sandbox deployment is not suitable for use in a full
              production environment.
</p>
</div>
</li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-requirements"></a>21.2.2 InnoDB Cluster Requirements</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444251650256"></a><p>
        Before installing a production deployment of InnoDB cluster,
        ensure that the server instances you intend to use meet the
        following requirements.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            InnoDB cluster uses Group Replication and therefore your
            server instances must meet the same requirements. See
            <a class="xref" href="group-replication.html#group-replication-requirements" title="18.9.1 Group Replication Requirements">Section 18.9.1, “Group Replication Requirements”</a>. AdminAPI
            provides the
            <code class="literal">dba.checkInstanceConfiguration()</code> method
            to verify that an instance meets the Group Replication
            requirements, and the
            <code class="literal">dba.configureInstance()</code> method to
            configure an instance to meet the requirements.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
              When using a sandbox deployment the instances are
              configured to meet these requirements automatically.
</p>
</div>
</li><li class="listitem"><p>
            Group Replication members can contain tables using a storage
            engine other than <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a>, for
            example <a class="link" href="storage-engines.html#myisam-storage-engine" title="16.2 The MyISAM Storage Engine"><code class="literal">MyISAM</code></a>. Such tables
            cannot be written to by Group Replication, and therefore
            when using InnoDB cluster. To be able to write to such
            tables with InnoDB cluster, convert all such tables to
            <a class="link" href="innodb-storage-engine.html" title="Chapter 15 The InnoDB Storage Engine"><code class="literal">InnoDB</code></a> before using the
            instance in an InnoDB cluster.
          </p></li><li class="listitem"><p>
            The Performance Schema must be enabled on any instance which
            you want to use with InnoDB cluster.
          </p></li><li class="listitem"><p>
            The provisioning scripts that MySQL Shell uses to configure
            servers for use in InnoDB cluster require access to
            Python. On Windows MySQL Shell includes Python and no user
            configuration is required. On Unix Python must be found as
            part of the shell environment. To check that your system has
            Python configured correctly issue:
          </p><pre data-lang="terminal" class="programlisting">$ <strong class="userinput"><code>/usr/bin/env python</code></strong></pre><p>
            If a Python interpreter starts, no further action is
            required. If the previous command fails, create a soft link
            between <code class="literal">/usr/bin/python</code> and your chosen
            Python binary. For more information, see
            <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-features.html#shell-supported-languages" target="_top">Supported Languages</a>.
          </p></li><li class="listitem"><p>
            From version 8.0.17, instances must use a unique
            <a class="link" href="replication.html#sysvar_server_id"><code class="literal">server_id</code></a> within a
            InnoDB cluster. When you use the
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance(<em class="replaceable"><code>instance</code></em>)</code>
            operation, if the <a class="link" href="replication.html#sysvar_server_id"><code class="literal">server_id</code></a>
            of <em class="replaceable"><code>instance</code></em> is already used by an
            instance in the cluster then the operation fails with an
            error.
</p></li></ul>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-methods-installing"></a>21.2.3 Methods of Installing</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444251626256"></a><a class="indexterm" name="idm46444251624768"></a><p>
        The method you use to install InnoDB cluster depends on the
        type of deployment you intend to use. For a sandbox deployment
        install the components of InnoDB cluster to a single machine.
        A sandbox deployment is local to a single machine, therefore the
        install needs to only be done once on the local machine. For a
        production deployment install the components to each machine
        that you intend to add to your cluster. A production deployment
        uses multiple remote host machines running MySQL server
        instances, so you need to connect to each machine using a tool
        such as SSH or Windows remote desktop to carry out tasks such as
        installing components. The following methods of installing
        InnoDB cluster are available:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Downloading and installing the components using the
            following documentation:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                MySQL Server - see <a class="xref" href="installing.html" title="Chapter 2 Installing and Upgrading MySQL">Chapter 2, <i>Installing and Upgrading MySQL</i></a>.
              </p></li><li class="listitem"><p>
                MySQL Shell - see
                <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-install.html" target="_top">Installing MySQL Shell</a>.
              </p></li><li class="listitem"><p>
                MySQL Router - see
                <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-installation.html" target="_top">Installing MySQL Router</a>.
</p></li></ul>
</div>
</li><li class="listitem"><p>
            On Windows you can use the MySQL Installer for Windows for a
            sandbox deployment. For details, see
            <a class="xref" href="installing.html#mysql-installer-workflow-innodb-cluster" title="2.3.3.3.1.1 High Availability">Section 2.3.3.3.1.1, “High Availability”</a>.
</p></li></ul>
</div>
<p>
        Once you have installed the software required by
        InnoDB cluster choose to follow either
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment" title="21.2.6 Sandbox Deployment of InnoDB Cluster">Section 21.2.6, “Sandbox Deployment of InnoDB Cluster”</a> or
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment" title="21.2.4 Production Deployment of InnoDB Cluster">Section 21.2.4, “Production Deployment of InnoDB Cluster”</a>.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-production-deployment"></a>21.2.4 Production Deployment of InnoDB Cluster</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444251610800"></a><p>
        When working in a production environment, the MySQL server
        instances which make up an InnoDB cluster run on multiple host
        machines as part of a network rather than on single machine as
        described in
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-sandbox-deployment" title="21.2.6 Sandbox Deployment of InnoDB Cluster">Section 21.2.6, “Sandbox Deployment of InnoDB Cluster”</a>.
        Before proceeding with these instructions you must install the
        required software to each machine that you intend to add as a
        server instance to your cluster, see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-methods-installing" title="21.2.3 Methods of Installing">Section 21.2.3, “Methods of Installing”</a>.
      </p><p>
        The following diagram illustrates the scenario you work with in
        this section:
</p>
<div class="figure">
<a name="production-servers-image"></a><p class="title"><b>Figure 21.2 Production Deployment</b></p>
<div class="figure-contents">

<div class="mediaobject">
<img src="images/production_servers.png" width="600" height="837" alt="Three MySQL servers are grouped together as a production InnoDB cluster. One of the servers is the primary instance, and the other two are secondary instances. The IP address for the primary server is 139.59.177.10, and the IP addresses for the two secondary instances are 139.59.177.11 and 139.59.177.12. MySQL Router connects a client application to the primary instance. The admin capability in MySQL Shell interacts directly with the production InnoDB cluster.">
</div>

</div>

</div>
<br class="figure-break">
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          Unlike a sandbox deployment, where all instances are deployed
          locally to one machine which AdminAPI has local file access
          to and can persist configuration changes, for a production
          deployment you must persist any configuration changes on the
          instance. How you do this depends on the version of MySQL
          running on the instance, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>.
</p>
</div>
<p>
        To pass a server's connection information to AdminAPI,
        use URI-like connection strings or a data dictionary; see
        <a class="xref" href="programs.html#connecting-using-uri-or-key-value-pairs" title="4.2.5 Connecting to the Server Using URI-Like Strings or Key-Value Pairs">Section 4.2.5, “Connecting to the Server Using URI-Like Strings or Key-Value Pairs”</a>. In
        this documentation, URI-like strings are shown.
      </p><p>
        The following sections describe how to deploy a production
        InnoDB cluster.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-user-privileges" title="User Privileges">User Privileges</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-users-created" title="User Accounts Created by InnoDB Cluster">User Accounts Created by InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-hostname" title="Configuring Hostname">Configuring Hostname</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-instance-ports" title="Configuring Ports">Configuring Ports</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-logging" title="Verbose Logging">Verbose Logging</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-production-instances" title="Configuring Production Instances">Configuring Production Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#create-cluster" title="Creating the Cluster">Creating the Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#add-instances-cluster" title="Adding Instances to a Cluster">Adding Instances to a Cluster</a></p></li></ul>
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-user-privileges"></a>User Privileges</h4>

</div>

</div>

</div>
<p>
          The user account used to administer an instance does not have
          to be the root account, however the user needs to be assigned
          full read and write privileges on the InnoDB cluster
          metadata tables in addition to full MySQL administrator
          privileges (<code class="literal">SUPER</code>, <code class="literal">GRANT
          OPTION</code>, <code class="literal">CREATE</code>,
          <code class="literal">DROP</code> and so on). The preferred method to
          create users to administer the cluster is using the
          <code class="literal">clusterAdmin</code> option with the
          <code class="literal">dba.configureInstance()</code>, and
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
          operations. In this procedure the user <code class="literal">ic</code>
          is shown in examples.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            The <code class="literal">clusterAdmin</code> user name and password
            must be the same on all instances that belong to a cluster.
</p>
</div>
<p>
          If only read operations are needed (such as for monitoring
          purposes), an account with more restricted privileges can be
          used. See <a class="xref" href="mysql-innodb-cluster-userguide.html#configure-innodb-cluster-user" title="Configuring Users for InnoDB Cluster">Configuring Users for InnoDB Cluster</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-users-created"></a>User Accounts Created by InnoDB Cluster</h4>

</div>

</div>

</div>
<p>
          As part of using Group Replication, InnoDB cluster creates
          internal recovery users which enable connections between the
          servers in the cluster. These users are internal to the
          cluster, and the user name of the generated users follows a
          naming scheme of
          <code class="literal">mysql_innodb_cluster_<em class="replaceable"><code>server_id</code></em>@%</code>,
          where <a class="link" href="replication.html#sysvar_server_id"><code class="literal">server_id</code></a> is unique to
          the instance. In versions earlier than 8.0.17 the user name of
          the generated users followed a naming scheme of
          <code class="literal">mysql_innodb_cluster_r[<em class="replaceable"><code>10_numbers</code></em>]</code>.
          The hostname used for the internal users depends on whether
          the <code class="literal">ipWhitelist</code> option has been configured.
          If <code class="literal">ipWhitelist</code> is not configured, it
          defaults to <code class="literal">AUTOMATIC</code> and the internal
          users are created using both the wildcard <code class="literal">%</code>
          character and <code class="literal">localhost</code> for the hostname
          value. When <code class="literal">ipWhitelist</code> has been
          configured, for each address in the
          <code class="literal">ipWhitelist</code> list an internal user is
          created.

          

          For more information, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#create-whitelist-servers" title="Creating a Whitelist of Servers">Creating a Whitelist of Servers</a>.
        </p><p>
          Each internal user has a randomly generated password.

          

          The randomly generated users are given the following grants:
        </p><pre data-lang="sql" class="programlisting">GRANT REPLICATION SLAVE ON *.* to <em class="replaceable"><code>internal_user</code></em>;</pre><p>
          The internal user accounts are created on the seed instance
          and then replicated to the other instances in the cluster. The
          internal users are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              generated when creating a new cluster by issuing
              <code class="literal">dba.createCluster()</code>
            </p></li><li class="listitem"><p>
              generated when adding a new instance to the cluster by
              issuing
              <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>.
</p></li></ul>
</div>
<p>
          In addition, the
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rejoinInstance()</code>
          operation can also result in a new internal user being
          generated when the <code class="literal">ipWhitelist</code> option is
          used to specify a hostname. For example by issuing:
        </p><pre data-lang="mysqlsh" class="programlisting">Cluster.rejoinInstance({ipWhitelist: "192.168.1.1/22"});</pre><p>
          all previously existing internal users are removed and a new
          internal user is created, taking into account the
          <code class="literal">ipWhitelist</code> value used.
        </p><p>
          For more information on the internal users required by Group
          Replication, see
          <a class="xref" href="group-replication.html#group-replication-user-credentials" title="18.2.1.3 User Credentials">Section 18.2.1.3, “User Credentials”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-production-hostname"></a>Configuring Hostname</h4>

</div>

</div>

</div>
<p>
          The production instances which make up a cluster run on
          separate machines, therefore each machine must have a unique
          host name and be able to resolve the host names of the other
          machines which run server instances in the cluster. If this is
          not the case, you can:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              configure each machine to map the IP of each other machine
              to a hostname. See your operating system documentation for
              details. This is the recommended solution.
            </p></li><li class="listitem"><p>
              set up a DNS service
            </p></li><li class="listitem"><p>
              configure the <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a>
              variable in the MySQL configuration of each instance to a
              suitable externally reachable address
</p></li></ul>
</div>
<p>
          InnoDB cluster supports using IP addresses instead of host
          names. From MySQL Shell 8.0.18, AdminAPI supports IPv6
          addresses if the target MySQL Server version is higher than
          8.0.13. When using MySQL Shell 8.0.18 or higher, if all
          cluster instances are running 8.0.14 or higher then you can
          use an IPv6 or hostname that resolves to an IPv6 address for
          instance connection strings and with options such as
          <code class="literal">localAddress</code>, <code class="literal">groupSeeds</code>
          and <code class="literal">ipWhitelist</code>. For more information on
          using IPv6 see <a class="xref" href="group-replication.html#group-replication-ipv6" title="18.4.5 Support For IPv6 And For Mixed IPv6 And IPv4 Groups">Section 18.4.5, “Support For IPv6 And For Mixed IPv6 And IPv4 Groups”</a>.
          Previous versions support IPv4 addresses only.
        </p><p>
          In this procedure the host name
          <code class="literal">ic-<em class="replaceable"><code>number</code></em></code> is
          used in examples.
        </p><p>
          To verify whether the hostname of a MySQL server is correctly
          configured, execute the following query to see how the
          instance reports its own address to other servers and try to
          connect to that MySQL server from other hosts using the
          returned address:
</p><pre data-lang="sql" class="programlisting">SELECT coalesce(@@report_host, @@hostname);</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="configuring-instance-ports"></a>Configuring Ports</h4>

</div>

</div>

</div>
<p>
          Instances that belong to a cluster have a
          <code class="literal">localAddress</code>, which is the
          <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>,
          and this address is used for internal connections between the
          instances in the cluster and is not for use by clients. When
          you create a cluster or add instances to a cluster, by default
          the <code class="literal">localAddress</code> port is calculated by
          multiplying the target instance's
          <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> value by 10 and then
          adding one to the result. For example, when the
          <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> of the target instance
          is the default value of 3306, the calculated
          <code class="literal">localAddress</code> port is 33061. You should
          ensure that port numbers used by your cluster instances are
          compatible with the way <code class="literal">localAddress</code> is
          calculated. For example, if the server instance being used to
          create a cluster has a <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a>
          number higher than 6553, the
          <code class="literal">dba.createCluster()</code> operation fails because
          the calculated <code class="literal">localAddress</code> port number
          exceeds the maximum valid port which is 65535. To avoid this
          situation either use a lower
          <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> value on the instances
          you use for InnoDB cluster, or manually assign the
          <code class="literal">localAddress</code> value, for example:
        </p><pre class="programlisting">mysql-js&gt; dba.createCluster('testCluster', {'localAddress':'icadmin@ic-1:33061'}</pre><p>
          If your instances are using SELinux, you need to ensure that
          the ports used by InnoDB cluster are open so that the
          instances can communicate with each other. See
          <a class="xref" href="group-replication.html#group-replication-using-selinux" title="How do I use Group Replication with SELinux?">How do I use Group Replication with SELinux?</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-persisting-settings"></a>Persisting Settings</h4>

</div>

</div>

</div>
<p>
          The AdminAPI commands you use to work with a cluster and its
          server instances modify the configuration of the instances.
          Depending on the way MySQL Shell is connected to an instance
          and the version of MySQL installed on the instance, these
          configuration changes can be persisted to the instance
          automatically. Persisting settings to the instance ensures
          that configuration changes are retained after the instance
          restarts, for background information see
          <a class="link" href="sql-statements.html#set-variable" title="13.7.6.1 SET Syntax for Variable Assignment"><code class="literal">SET
          PERSIST</code></a>. This is essential for reliable cluster
          usage, for example if settings are not persisted then an
          instance which has been added to a cluster does not rejoin the
          cluster after a restart because configuration changes are
          lost. Persisting changes is required after the following
          operations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">dba.configureInstance()</code>
            </p></li><li class="listitem"><p>
              <code class="literal">dba.createCluster()</code>
            </p></li><li class="listitem"><p>
              <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
            </p></li><li class="listitem"><p>
              <code class="literal"><em class="replaceable"><code>Cluster</code></em>.removeInstance()</code>
            </p></li><li class="listitem"><p>
              <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rejoinInstance()</code>
</p></li></ul>
</div>
<p>
          Instances which meet the following requirements support
          persisting configuration changes automatically:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              the instance is running MySQL version 8.0.11 or later
            </p></li><li class="listitem"><p>
              <a class="link" href="server-administration.html#sysvar_persisted_globals_load"><code class="literal">persisted_globals_load</code></a> is
              set to <code class="literal">ON</code>
            </p></li><li class="listitem"><p>
              the instance has not been started with the
              <a class="link" href="server-administration.html#option_mysqld_no-defaults"><code class="option">--no-defaults</code></a> option
</p></li></ul>
</div>
<p>
          Instances which do not meet these requirements do not support
          persisting configuration changes automatically, when
          AdminAPI operations result in changes to the instance's
          settings to be persisted you receive warnings such as:
        </p><pre data-lang="simple" class="programlisting">	
WARNING: On instance 'localhost:3320' membership change cannot be persisted since MySQL version 5.7.21 
does not support the SET PERSIST command (MySQL version &gt;= 8.0.5 required). Please use the 
&lt;Dba&gt;.configureLocalInstance command locally to persist the changes.
</pre><p>
          When AdminAPI commands are issued against the MySQL instance
          which MySQL Shell is currently running on, in other words the
          local instance, MySQL Shell persists configuration changes
          directly to the instance. On local instances which support
          persisting configuration changes automatically, configuration
          changes are persisted to the instance's
          <code class="filename">mysqld-auto.cnf</code> file and the
          configuration change does not require any further steps. On
          local instances which do not support persisting configuration
          changes automatically, you need to make the changes locally,
          see <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-local-instances" title="Configuring Instances with dba.configureLocalInstance()">Configuring Instances with
        <code class="literal">dba.configureLocalInstance()</code></a>.
        </p><p>
          When run against a remote instance, in other words an instance
          other than the one which MySQL Shell is currently running on,
          if the instance supports persisting configuration changes
          automatically, the AdminAPI commands persist configuration
          changes to the instance's <code class="filename">mysql-auto.conf</code>
          option file. If a remote instance does not support persisting
          configuration changes automatically, the AdminAPI commands
          can not automatically configure the instance's option file.
          This means that AdminAPI commands can read information from
          the instance, for example to display the current
          configuration, but changes to the configuration cannot be
          persisted to the instance's option file. In this case, you
          need to persist the changes locally, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-local-instances" title="Configuring Instances with dba.configureLocalInstance()">Configuring Instances with
        <code class="literal">dba.configureLocalInstance()</code></a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="mysql-innodb-cluster-logging"></a>Verbose Logging</h4>

</div>

</div>

</div>
<p>
          When working with a production deployment it can be useful to
          configure verbose logging for MySQL Shell, the information in
          the log can help you to find and resolve any issues that might
          occur when you are preparing server instances to work as part
          of InnoDB cluster. To start MySQL Shell with a verbose
          logging level use the
          <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysqlsh.html#option_mysqlsh_log-level" target="_top"><code class="option">--log-level</code></a> option:
        </p><pre data-lang="terminal" class="programlisting">shell&gt; <strong class="userinput"><code>mysqlsh --log-level=DEBUG3</code></strong>
</pre><p>
          The <code class="literal">DEBUG3</code> is recommended, see
          <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysqlsh.html#option_mysqlsh_log-level" target="_top"><code class="option">--log-level</code></a> for more
          information. When <code class="literal">DEBUG3</code> is set the
          MySQL Shell log file contains lines such as <code class="literal">Debug:
          execute_sql( ... )</code> which contain the SQL queries
          that are executed as part of each AdminAPI call. The log
          file generated by MySQL Shell is located in
          <code class="filename">~/.mysqlsh/mysqlsh.log</code> for Unix-based
          systems; on Microsoft Windows systems it is located in
          <code class="filename">%APPDATA%\MySQL\mysqlsh\mysqlsh.log</code>. See
          <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-application-log.html" target="_top">MySQL Shell Logging and Debug</a> for more
          information.
        </p><p>
          In addition to enabling the MySQL Shell log level, you can
          configure the amount of output AdminAPI provides in
          MySQL Shell after issuing each command. To enable the amount
          of AdminAPI output, in MySQL Shell issue:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; dba.verbose=2</pre><p>
          This enables the maximum output from AdminAPI calls. The
          available levels of output are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              0 or OFF is the default. This provides minimal output and
              is the recommended level when not troubleshooting.
            </p></li><li class="listitem"><p>
              1 or ON adds verbose output from each call to the
              AdminAPI.
            </p></li><li class="listitem"><p>
              2 adds debug output to the verbose output providing full
              information about what each call to AdminAPI executes.
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="configuring-production-instances"></a>Configuring Production Instances</h4>

</div>

</div>

</div>
<p>
          AdminAPI provides the
          <code class="literal">dba.configureInstance()</code> function that
          checks if an instance is suitably configured for
          InnoDB cluster usage, and configures the instance if it
          finds any settings which are not compatible with
          InnoDB cluster. You run the
          <code class="literal">dba.configureInstance()</code> command against an
          instance and it checks all of the settings required to enable
          the instance to be used for InnoDB cluster usage. If the
          instance does not require configuration changes, there is no
          need to modify the configuration of the instance, and the
          <code class="literal">dba.configureInstance()</code> command output
          confirms that the instance is ready for InnoDB cluster
          usage. If any changes are required to make the instance
          compatible with InnoDB cluster, a report of the incompatible
          settings is displayed, and you can choose to let the command
          make the changes to the instance's option file. Depending on
          the way MySQL Shell is connected to the instance, and the
          version of MySQL running on the instance, you can make these
          changes permanent by persisting them to a remote instance's
          option file, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>.
          Instances which do not support persisting configuration
          changes automatically require that you configure the instance
          locally, see <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-local-instances" title="Configuring Instances with dba.configureLocalInstance()">Configuring Instances with
        <code class="literal">dba.configureLocalInstance()</code></a>.
          Alternatively you can make the changes to the instance's
          option file manually, see <a class="xref" href="programs.html#option-files" title="4.2.2.2 Using Option Files">Section 4.2.2.2, “Using Option Files”</a> for
          more information. Regardless of the way you make the
          configuration changes, you might have to restart MySQL to
          ensure the configuration changes are detected.
        </p><p>
          The syntax of the <code class="literal">dba.configureInstance()</code>
          command is:
        </p><pre data-lang="mysqlsh" class="programlisting">dba.configureInstance([<em class="replaceable"><code>instance</code></em>][, <em class="replaceable"><code>options</code></em>])
</pre><p>
          where <em class="replaceable"><code>instance</code></em> is an instance
          definition, and <em class="replaceable"><code>options</code></em> is a data
          dictionary with additional options to configure the operation.
          The command returns a descriptive text message about the
          operation's result.
        </p><p>
          The <em class="replaceable"><code>instance</code></em> definition is the
          connection data for the instance, see
          <a class="xref" href="programs.html#connecting-using-uri-or-key-value-pairs" title="4.2.5 Connecting to the Server Using URI-Like Strings or Key-Value Pairs">Section 4.2.5, “Connecting to the Server Using URI-Like Strings or Key-Value Pairs”</a>. If
          the target instance already belongs to an InnoDB cluster an
          error is generated and the process fails.
        </p><p>
          The options dictionary can contain the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">mycnfPath</code> - the path to the MySQL
              option file of the instance.
            </p></li><li class="listitem"><p>
              <code class="literal">outputMycnfPath</code> - alternative output
              path to write the MySQL option file of the instance.
            </p></li><li class="listitem"><p>
              <code class="literal">password</code> - the password to be used by
              the connection.
            </p></li><li class="listitem"><p>
              <code class="literal">clusterAdmin</code> - the name of an
              InnoDB cluster administrator user to be created. The
              supported format is the standard MySQL account name
              format. Supports identifiers or strings for the user name
              and host name. By default if unquoted it assumes input is
              a string.
            </p></li><li class="listitem"><p>
              <code class="literal">clusterAdminPassword</code> - the password for
              the InnoDB cluster administrator account being created
              using <code class="literal">clusterAdmin</code>. Although you can
              specify using this option, this is a potential security
              risk. If you do not specify this option, but do specify
              the <code class="literal">clusterAdmin</code> option, you are
              prompted for the password at the interactive prompt.
            </p></li><li class="listitem"><p>
              <code class="literal">clearReadOnly</code> - a boolean value used to
              confirm that
              <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> should be
              set to off, see
              <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a>.
            </p></li><li class="listitem"><p>
              <code class="literal">interactive</code> - a boolean value used to
              disable the interactive wizards in the command execution,
              so that prompts are not provided to the user and
              confirmation prompts are not shown.
            </p></li><li class="listitem"><p>
              <code class="literal">restart</code> - a boolean value used to
              indicate that a remote restart of the target instance
              should be performed to finalize the operation.
</p></li></ul>
</div>
<p>
          Although the connection password can be contained in the
          instance definition, this is insecure and not recommended. Use
          the MySQL Shell
          <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-pluggable-password-store.html" target="_top">Pluggable Password Store</a> to
          store instace passwords securely.
        </p><p>
          Once <code class="literal">dba.configureInstance()</code> is issued
          against an instance, the command checks if the instance's
          settings are suitable for InnoDB cluster usage. A report is
          displayed which shows the settings required by
          InnoDB cluster

          

          . If the instance does not require any changes to its settings
          you can use it in an InnoDB cluster, and can proceed to
          <a class="xref" href="mysql-innodb-cluster-userguide.html#create-cluster" title="Creating the Cluster">Creating the Cluster</a>. If the instance's settings
          are not valid for InnoDB cluster usage the
          <code class="literal">dba.configureInstance()</code> command displays
          the settings which require modification. Before configuring
          the instance you are prompted to confirm the changes shown in
          a table with the following information:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              <code class="literal">Variable</code> - the invalid configuration
              variable.
            </p></li><li class="listitem"><p>
              <code class="literal">Current Value</code> - the current value for
              the invalid configuration variable.
            </p></li><li class="listitem"><p>
              <code class="literal">Required Value</code> - the required value for
              the configuration variable.
</p></li></ul>
</div>
<p>
          How you proceed depends on whether the instance supports
          persisting settings, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>.
          When <code class="literal">dba.configureInstance()</code> is issued
          against the MySQL instance which MySQL Shell is currently
          running on, in other words the local instance, it attempts to
          automatically configure the instance. When
          <code class="literal">dba.configureInstance()</code> is issued against a
          remote instance, if the instance supports persisting
          configuration changes automatically, you can choose to do
          this.

          

          If a remote instance does not support persisting the changes
          to configure it for InnoDB cluster usage, you have to
          configure the instance locally. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-local-instances" title="Configuring Instances with dba.configureLocalInstance()">Configuring Instances with
        <code class="literal">dba.configureLocalInstance()</code></a>.
        </p><p>
          In general, a restart of the instance is not required after
          <code class="literal">dba.configureInstance()</code> configures the
          option file, but for some specific settings a restart might be
          required. This information is shown in the report generated
          after issuing <code class="literal">dba.configureInstance()</code>. If
          the instance supports the
          <a class="link" href="sql-statements.html#restart" title="13.7.8.8 RESTART Statement"><code class="literal">RESTART</code></a> statement, MySQL Shell
          can shutdown and then start the instance. This ensures that
          the changes made to the instance's option file are detected by
          mysqld. For more information see
          <a class="link" href="sql-statements.html#restart" title="13.7.8.8 RESTART Statement"><code class="literal">RESTART</code></a>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            After executing a <a class="link" href="sql-statements.html#restart" title="13.7.8.8 RESTART Statement"><code class="literal">RESTART</code></a>
            statement, the current connection to the instance is lost.
            If auto-reconnect is enabled, the connection is
            reestablished after the server restarts. Otherwise, the
            connection must be reestablished manually.
</p>
</div>
<p>
          The <code class="literal">dba.configureInstance()</code> method verifies
          that a suitable user is available for cluster usage, which is
          used for connections between members of the cluster, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-user-privileges" title="User Privileges">User Privileges</a>. The
          recommended way to add a suitable user is to use the
          <code class="literal">clusterAdmin</code> option, which enables you to
          configure the cluster user and password when calling the
          operation. For example:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; dba.configureInstance('root@ic-1:3306', \ 
{clusterAdmin: "'icadmin'@'ic-1%'"});</pre><p>
          The interactive prompt requests the password required by the
          specified user. This option should be used with a connection
          based on a user which has the privileges to create users with
          suitable privileges, in this example the root user is used.
          The created <code class="literal">clusterAdmin</code> user is granted
          the privileges to be able to administer the cluster. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#configure-innodb-cluster-user" title="Configuring Users for InnoDB Cluster">Configuring Users for InnoDB Cluster</a> for more
          information. The format of the user names accepted by the
          <code class="literal">clusterAdmin</code> option follows the standard
          MySQL account name format, see
          <a class="xref" href="security.html#account-names" title="6.2.4 Specifying Account Names">Section 6.2.4, “Specifying Account Names”</a>. In this procedure the name
          <code class="literal">icadmin</code> is used, and that name is required
          for further operations such as adding instances to the
          cluster.
        </p><p>
          If you do not specify a user to administer the cluster, in
          interactive mode a wizard enables you to choose one of the
          following options:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              enable remote connections for the root user

              
            </p></li><li class="listitem"><p>
              create a new user, the equivalent of specifying the
              <code class="literal">clusterAdmin</code> option
            </p></li><li class="listitem"><p>
              no automatic configuration, in which case you need to
              manually create the user
</p></li></ul>
</div>
<p>
          The following example demonstrates the option to create a new
          user for cluster usage.
        </p><pre data-lang="mysqlsh" class="programlisting">	
mysql-js&gt; <strong class="userinput"><code>dba.configureLocalInstance('root@localhost:3306')</code></strong>

Please provide the password for 'root@localhost:3306':

Please specify the path to the MySQL configuration file: /etc/mysql/mysql.conf.d/mysqld.cnf
Validating instance...

The configuration has been updated but it is required to restart the server.
{
  "config_errors": [
    {
      "action": "restart",
      "current": "OFF",
      "option": "enforce_gtid_consistency",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "gtid_mode",
      "required": "ON"
      },
    {
      "action": "restart",
      "current": "0",
      "option": "log_bin",
      "required": "1"
    },
    {
      "action": "restart",
      "current": "0",
      "option": "log_slave_updates",
      "required": "ON"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "master_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "FILE",
      "option": "relay_log_info_repository",
      "required": "TABLE"
    },
    {
      "action": "restart",
      "current": "OFF",
      "option": "transaction_write_set_extraction",
      "required": "XXHASH64"
    }
  ],
  "errors": [],
  "restart_required": true,
  "status": "error"
}
mysql-js&gt;
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If the instance has
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
            might need to confirm that AdminAPI can set
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
            information.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="create-cluster"></a>Creating the Cluster</h4>

</div>

</div>

</div>
<p>
          Once you have prepared your instances, use the
          <code class="literal">dba.createCluster()</code> function to create the
          cluster, using the instance which MySQL Shell is connected to
          as the seed instance for the cluster. The seed instance is
          replicated to the other instances that you add to the cluster,
          making them replicas of the seed instance. In this procedure
          the ic-1 instance is used as the seed. When you issue
          <code class="literal">dba.createCluster(<em class="replaceable"><code>name</code></em>)</code>
          MySQL Shell creates a classic MySQL protocol session to the server
          instance connected to the MySQL Shell's current global
          session. For example, to create a cluster called
          <em class="replaceable"><code>testCluster</code></em> and assign the returned
          cluster to a variable called <code class="literal">cluster</code>:
        </p><pre data-lang="mysqlsh" class="programlisting">      
mysql-js&gt; <strong class="userinput"><code>var cluster = dba.createCluster('<em class="replaceable"><code>testCluster</code></em>')</code></strong>

Validating instance at icadmin@ic-1:3306...

This instance reports its own address as ic-1

Instance configuration is suitable.
Creating InnoDB cluster 'testCluster' on 'icadmin@ic-1:3306'...

Adding Seed Instance...
Cluster successfully created. Use Cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.
</pre><p>
          This pattern of assigning the returned cluster to a variable
          enables you to then execute further operations against the
          cluster using the Cluster object's methods. The returned
          Cluster object uses a new session, independent from the
          MySQL Shell's global session. This ensures that if you change
          the MySQL Shell global session, the Cluster object maintains
          its session to the instance.
        </p><p>
          The <code class="literal">dba.createCluster()</code> operation supports
          MySQL Shell's <code class="literal">interactive</code> option. When
          <code class="literal">interactive</code> is on, prompts appear in the
          following situations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              when run on an instance that belongs to a cluster and the
              <code class="literal">adoptFromGr</code> option is false, you are
              asked if you want to adopt an existing cluster
            </p></li><li class="listitem"><p>
              when the <code class="literal">force</code> option is not used (not
              set to <code class="literal">true</code>), you are asked to confirm
              the creation of a multi-primary cluster
</p></li></ul>
</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Note
</div>
<p>
            If you encounter an error related to metadata being
            inaccessible you might have the loopback network interface
            configured. For correct InnoDB cluster usage disable the
            loopback interface.
</p>
</div>
<p>
          To check the cluster has been created, use the cluster
          instance's <code class="literal">status()</code> function. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking a cluster's Status with Cluster.status()">Checking a cluster's Status with
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code></a>.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            Once server instances belong to a cluster it is important to
            only administer them using MySQL Shell and AdminAPI.
            Attempting to manually change the configuration of Group
            Replication on an instance once it has been added to a
            cluster is not supported. Similarly, modifying server
            variables critical to InnoDB cluster, such as
            <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a>, after an
            instance is configured using AdminAPI is not supported.
</p>
</div>
<p>
          

          When you create a cluster using MySQL Shell 8.0.14 and later,
          you can set the timeout before instances are expelled from the
          cluster, for example when they become unreachable. Pass the
          <code class="literal">expelTimeout</code> option to the
          <code class="literal">dba.createCluster()</code> operation, which
          configures the
          <a class="link" href="group-replication.html#sysvar_group_replication_member_expel_timeout"><code class="literal">group_replication_member_expel_timeout</code></a>
          variable on the seed instance. The
          <code class="literal">expelTimeout</code> option can take an integer
          value in the range of 0 to 3600. All instances running MySQL
          server 8.0.13 and later which are added to a cluster with
          <code class="literal">expelTimeout</code> configured are automatically
          configured to have the same <code class="literal">expelTimeout</code>
          value as configured on the seed instance.
        </p><p>
          For information on the other options which you can pass to
          <code class="literal">dba.createCluster()</code>, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-working-with-cluster" title="21.5 Working with InnoDB Cluster">Section 21.5, “Working with InnoDB Cluster”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="add-instances-cluster"></a>Adding Instances to a Cluster</h4>

</div>

</div>

</div>
<p>
          Use the
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance(<em class="replaceable"><code>instance</code></em>)</code>
          function to add more instances to the cluster, where
          <em class="replaceable"><code>instance</code></em> is connection information
          to a configured instance, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-production-instances" title="Configuring Production Instances">Configuring Production Instances</a>. From
          version 8.0.17, Group Replication implements compatibility
          policies which consider the patch version of the instances,
          and the
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
          operation detects this and in the event of an incompatibility
          the operation terminates with an error. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#checking-version-on-instances" title="Checking the MySQL Version on Instances">Checking the MySQL Version on Instances</a> and
          <a class="xref" href="group-replication.html#group-replication-online-upgrade-combining-versions" title="18.7.1 Combining Different Member Versions in a Group">Section 18.7.1, “Combining Different Member Versions in a Group”</a>
        </p><p>
          You need a minimum of three instances in the cluster to make
          it tolerant to the failure of one instance. Adding further
          instances increases the tolerance to failure of an instance.
          To add an instance to the cluster issue:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.addInstance('icadmin@ic-2:3306')</code></strong>
A new instance will be added to the InnoDB cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

Please provide the password for 'icadmin@ic-2:3306': ********
Adding instance to the cluster ...

Validating instance at ic-2:3306...

This instance reports its own address as ic-2

Instance configuration is suitable.

The instance 'icadmin@ic-2:3306' was successfully added to the cluster.
</pre><p>
          If you are using MySQL 8.0.17 or later you can choose how the
          instance recovers the transactions it requires to synchronize
          with the cluster. Only when the joining instance has recovered
          all of the transactions previously processed by the cluster
          can it then join as an online instance and begin processing
          transactions. For more information, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-clone-deployment" title="21.2.5 Using MySQL Clone with InnoDB cluster">Section 21.2.5, “Using MySQL Clone with InnoDB cluster”</a>.
        </p><p>
          Also in 8.0.17 and later, you can configure how
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
          behaves, letting recovery operations proceed in the background
          or monitoring different levels of progress in MySQL Shell.
        </p><p>
          Depending on which option you chose to recover the instance
          from the cluster, you see different output in MySQL Shell.
          Suppose that you are adding the instance ic-2 to the cluster,
          and ic-1 is the seed or donor.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              When you use MySQL Clone to recover an instance from the
              cluster, the output looks like:
            </p><pre class="programlisting">Validating instance at ic-2:3306...

This instance reports its own address as ic-2:3306

Instance configuration is suitable.
A new instance will be added to the InnoDB cluster. Depending on the amount of
data on the cluster this might take from a few seconds to several hours.

Adding instance to the cluster...

Monitoring recovery process of the new cluster member. Press ^C to stop monitoring and let it continue in background.
Clone based state recovery is now in progress.

NOTE: A server restart is expected to happen as part of the clone process. If the
server does not support the RESTART command or does not come back after a
while, you may need to manually start it back.

* Waiting for clone to finish...
NOTE: ic-2:3306 is being cloned from ic-1:3306
** Stage DROP DATA: Completed
** Clone Transfer  
    FILE COPY  ############################################################  100%  Completed
    PAGE COPY  ############################################################  100%  Completed
    REDO COPY  ############################################################  100%  Completed

NOTE: ic-2:3306 is shutting down...

* Waiting for server restart... ready
* ic-2:3306 has restarted, waiting for clone to finish...
** Stage RESTART: Completed
* Clone process has finished: 2.18 GB transferred in 7 sec (311.26 MB/s)

State recovery already finished for 'ic-2:3306'

The instance 'ic-2:3306' was successfully added to the cluster.</pre><p>
              The warnings about server restart should be observed, you
              might have to manually restart an instance. See
              <a class="xref" href="sql-statements.html#restart" title="13.7.8.8 RESTART Statement">Section 13.7.8.8, “RESTART Statement”</a>.
            </p></li><li class="listitem"><p>
              When you use incremental recovery to recover an instance
              from the cluster, the output looks like:
            </p><pre class="programlisting">Incremental distributed state recovery is now in progress.

* Waiting for incremental recovery to finish...
NOTE: 'ic-2:3306' is being recovered from 'ic-1:3306'
* Distributed recovery has finished</pre></li></ul>
</div>
<p>
          To cancel the monitoring of the recovery phase, issue
          <span class="keycap"><strong>CONTROL+C</strong></span>. This stops the monitoring but the
          recovery process continues in the background. The
          <code class="literal">waitRecovery</code> integer option can be used
          with the
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
          operation to control the behavior of the command regarding the
          recovery phase. The following values are accepted:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              0: do not wait and let the recovery process finish in the
              background;
            </p></li><li class="listitem"><p>
              1: wait for the recovery process to finish;
            </p></li><li class="listitem"><p>
              2: wait for the recovery process to finish; and show
              detailed static progress information;
            </p></li><li class="listitem"><p>
              3: wait for the recovery process to finish; and show
              detailed dynamic progress information (progress bars);
</p></li></ul>
</div>
<p>
          By default, if the standard output which MySQL Shell is
          running on refers to a terminal, the
          <code class="literal">waitRecovery</code> option defaults to 3.
          Otherwise, it defaults to 2. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#innodb-cluster-monitoring-recovery" title="Monitoring Recovery Operations">Monitoring Recovery Operations</a>.
        </p><p>
          To verify the instance has been added, use the cluster
          instance's <code class="literal">status()</code> function. For
          example this is the status output of a sandbox cluster after
          adding a second instance:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.status()</code></strong>
{
    "clusterName": "testCluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "primary": "ic-1:3306", 
        "ssl": "REQUIRED", 
        "status": "OK_NO_TOLERANCE", 
        "statusText": "Cluster is NOT tolerant to any failures.", 
        "topology": {
            "ic-1:3306": {
                "address": "ic-1:3306", 
                "mode": "R/W", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }, 
            "ic-2:3306": {
                "address": "ic-2:3306", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }
        }
    }, 
    "groupInformationSourceMember": "mysql://icadmin@ic-1:3306"
}
</pre><p>
          How you proceed depends on whether the instance is local or
          remote to the instance MySQL Shell is running on, and whether
          the instance supports persisting configuration changes
          automatically, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>. If
          the instance supports persisting configuration changes
          automatically, you do not need to persist the settings
          manually and can either add more instances or continue to the
          next step. If the instance does not support persisting
          configuration changes automatically, you have to configure the
          instance locally. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-local-instances" title="Configuring Instances with dba.configureLocalInstance()">Configuring Instances with
        <code class="literal">dba.configureLocalInstance()</code></a>. This is
          essential to ensure that instances rejoin the cluster in the
          event of leaving the cluster.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If the instance has
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
            might need to confirm that AdminAPI can set
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
            information.
</p>
</div>
<p>
          Once you have your cluster deployed you can configure MySQL Router
          to provide high availability, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-using-router" title="21.4 Using MySQL Router with InnoDB Cluster">Section 21.4, “Using MySQL Router with InnoDB Cluster”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-clone-deployment"></a>21.2.5 Using MySQL Clone with InnoDB cluster</h3>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-working-with-clone">21.2.5.1 Working with a Cluster that uses MySQL Clone</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444251321968"></a><p>
        In MySQL 8.0.17, InnoDB cluster integrates the MySQL Clone
        plugin to provide automatic provisioning of joining instances.
        The process of retrieving the cluster's data so that the
        instance can synchronize with the cluster is called distributed
        recovery. When an instance needs to recover a cluster's
        transactions we distinguish between the
        <span class="emphasis"><em>donor</em></span>, which is the cluster instance that
        provides the data, and the <span class="emphasis"><em>receiver</em></span>, which
        is the instance that receives the data from the donor. In
        previous versions, Group Replication provided only asynchronous
        replication to recover the transactions required for the joining
        instance to synchronize with the cluster so that it could join
        the cluster. For a cluster with a large amount of previously
        processed transactions it could take a long time for the new
        instance to recover all of the transactions before being able to
        join the cluster. Or a cluster which had purged GTIDs, for
        example as part of regular maintenance, could be missing some of
        the transactions required to recover the new instance. In such
        cases the only alternative was to manually provision the
        instance using tools such as MySQL Enterprise Backup, as shown in
        <a class="xref" href="group-replication.html#group-replication-enterprise-backup" title="18.4.6 Using MySQL Enterprise Backup with Group Replication">Section 18.4.6, “Using MySQL Enterprise Backup with Group Replication”</a>.
      </p><p>
        MySQL Clone provides an alternative way for an instance to
        recover the transactions required to synchronize with a cluster.
        Instead of relying on asynchronous replication to recover the
        transactions, MySQL Clone takes a snapshot of the data on the
        donor instance and then transfers the snapshot to the receiver.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          All previous data in the receiver is destroyed during a clone
          operation. All MySQL settings not stored in tables are however
          maintained.
</p>
</div>
<p>
        Once a clone operation has transferred the snapshot to the
        receiver, if the cluster has processed transactions while the
        snapshot was being transferred, asynchronous replication is used
        to recover any required data for the receiver to be synchronized
        with the cluster. This can be much more efficient than the
        instance recovering all of the transactions using asynchronous
        replication, and avoids any issues caused by purged GTIDs,
        enabling you to quickly provision new instances for
        InnoDB cluster. For more information, see
        <a class="xref" href="server-administration.html#clone-plugin" title="5.6.7 The Clone Plugin">Section 5.6.7, “The Clone Plugin”</a> and
        <a class="xref" href="group-replication.html#group-replication-cloning" title="18.4.3.1 Cloning for Distributed Recovery">Section 18.4.3.1, “Cloning for Distributed Recovery”</a>
      </p><p>
        In contrast to using MySQL Clone, incremental recovery is the
        process where an instance joining a cluster uses only
        asynchronous replication to recover an instance from the
        cluster. When an InnoDB cluster is configured to use MySQL
        Clone, instances which join the cluster use either MySQL Clone
        or incremental recovery to recover the cluster's transactions.
        By default, the cluster automatically chooses the most suitable
        method, but you can optionally configure this behavior, for
        example to force cloning, which replaces any transactions
        already processed by the joining instance. When you are using
        MySQL Shell in interactive mode, the default, if the cluster is
        not sure it can proceed with recovery it provides an interactive
        prompt. This section describes the different options you are
        offered, and the different scenarios which influence which of
        the options you can choose.
      </p><p>
        In addition, the output of
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>
        for members in <code class="literal">RECOVERING</code> state includes
        recovery progress information to enable you to easily monitor
        recovery operations, whether they are using MySQL Clone or
        incremental recovery. InnoDB cluster provides additional
        information about instances using MySQL Clone in the output of
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h4 class="title"><a name="mysql-innodb-cluster-working-with-clone"></a>21.2.5.1 Working with a Cluster that uses MySQL Clone</h4>
</div>
</div>
</div>
<p>
          An InnoDB cluster that uses MySQL Clone provides the
          following additional behavior.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h5 class="title"><a name="innodb-cluster-clone-create-cluster"></a><code class="literal">dba.createCluster()</code> and MySQL Clone</h5>
</div>
</div>
</div>
<p>
            From version 8.0.17, by default when a new cluster is
            created on an instance where the MySQL Clone plugin is
            available then it is automatically installed and the cluster
            is configured to support cloning. The InnoDB cluster
            recovery accounts are created with the required
            <a class="link" href="security.html#priv_backup-admin"><code class="literal">BACKUP_ADMIN</code></a> privilege.
          </p><p>
            Set the <code class="literal">disableClone</code> Boolean option to
            <code class="literal">true</code> to disable MySQL Clone for the
            cluster. In this case a metadata entry is added for this
            configuration and the MySQL Clone plugin is uninstalled if
            it is installed. You can set the
            <code class="literal">disableClone</code> option when you issue
            <code class="literal">dba.createCluster()</code>, or at any time when
            the cluster is running using
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.setOption()</code>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="innodb-cluster-clone-add-instance"></a><code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance(<em class="replaceable"><code>instance</code></em>)</code>
and MySQL Clone</h5>
</div>
</div>
</div>
<p>
            MySQL Clone can be used for a joining
            <em class="replaceable"><code>instance</code></em> if the new instance is
            running MySQL 8.0.17 or later, and there is at least one
            donor in the cluster (included in the
            <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
            list) running MySQL 8.0.17 or later. A cluster using MySQL
            Clone follows the behavior documented at
            <a class="xref" href="mysql-innodb-cluster-userguide.html#add-instances-cluster" title="Adding Instances to a Cluster">Adding Instances to a Cluster</a>, with the addition
            of a possible choice of how to transfer the data required to
            recover the instance from the cluster. How
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance(<em class="replaceable"><code>instance</code></em>)</code>
            behaves depends on the following factors:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                Whether MySQL Clone is supported.
              </p></li><li class="listitem"><p>
                Whether incremental recovery is possible or not, which
                depends on the availability of binary logs. For example,
                if a donor instance has all binary logs required
                (<code class="literal">GTID_PURGED</code> is empty) then
                incremental recovery is possible. If no cluster instance
                has all binary logs required then incremental recovery
                is not possible.
              </p></li><li class="listitem"><p>
                Whether incremental recovery is appropriate or not. Even
                though incremental recovery might be possible, because
                it has the potential to clash with data already on the
                instance, the GTID sets on the donor and receiver are
                checked to make sure that incremental recovery is
                appropriate. The following are possible results of the
                comparison:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                    New: the receiver has an empty
                    <code class="literal">GTID_EXECUTED</code> GTID set
                  </p></li><li class="listitem"><p>
                    Identical: the receiver has a GTID set identical to
                    the donor’s GTID set
                  </p></li><li class="listitem"><p>
                    Recoverable: the receiver has a GTID set that is
                    missing transactions but these can be recovered from
                    the donor
                  </p></li><li class="listitem"><p>
                    Irrecoverable: the donor has a GTID set that is
                    missing transactions, possibly they have been purged
                  </p></li><li class="listitem"><p>
                    Diverged: the GTID sets of the donor and receiver
                    have diverged
</p></li></ul>
</div>
<p>
                When the result of the comparison is determined to be
                Identical or Recoverable, incremental recovery is
                considered appropriate. When the result of the
                comparison is determined to be Irrecoverable or
                Diverged, incremental recovery is not considered
                appropriate.
              </p><p>
                For an instance considered New, incremental recovery
                cannot be considered appropriate because it is
                impossible to determine if the binary logs have been
                purged, or even if the <code class="literal">GTID_PURGED</code>
                and <code class="literal">GTID_EXECUTED</code> variables were
                reset. Alternatively, it could be that the server had
                already processed transactions before binary logs and
                GTIDs were enabled. Therefore in interactive mode, you
                have to confirm that you want to use incremental
                recovery.
              </p></li><li class="listitem"><p>
                The state of the <code class="literal">gtidSetIsComplete</code>
                option. If you are sure a cluster has been created with
                a complete GTID set, and therefore instances with empty
                GTID sets can be added to it without extra
                confirmations, set the cluster level
                <code class="literal">gtidSetIsComplete</code> Boolean option to
                <code class="literal">true</code>.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
                  Setting the <code class="literal">gtidSetIsComplete</code>
                  option to <code class="literal">true</code> means that joining
                  servers are recovered regardless of any data they
                  contain, use with caution. If you try to add an
                  instance which has applied transactions you risk data
                  corruption.
</p>
</div>
</li></ul>
</div>
<p>
            The combination of these factors influence how instances
            join the cluster when you issue
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>.
            The <code class="literal">recoveryMethod</code> option is set to
            <code class="literal">auto</code> by default, which means that in
            MySQL Shell's interactive mode, the cluster selects the
            best way to recover the instance from the cluster, and the
            prompts advise you how to proceed. In other words the
            cluster recommends using MySQL Clone or incremental recovery
            based on the best approach and what the server supports. If
            you are not using interactive mode and are scripting
            MySQL Shell, you must set <code class="literal">recoveryMethod</code>
            to the type of recovery you want to use - either
            <code class="literal">clone</code> or <code class="literal">incremental</code>.
            This section explains the different possible scenarios.
          </p><p>
            When you are using MySQL Shell in interactive mode, the
            main prompt with all of the possible options for adding the
            instance is:
          </p><pre class="programlisting">Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone):</pre><p>
            Depending on the factors mentioned, you might not be offered
            all of these options. The scenarios described later in this
            section explain which options you are offered. The options
            offered by this prompt are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                <span class="emphasis"><em>Clone</em></span>: choose this option to clone
                the donor to the instance which you are adding to the
                cluster, deleting any transactions the instance
                contains. The MySQL Clone plugin is automatically
                installed. The InnoDB cluster recovery accounts are
                created with the required
                <a class="link" href="security.html#priv_backup-admin"><code class="literal">BACKUP_ADMIN</code></a> privilege.
                Assuming you are adding an instance which is either
                empty (has not processed any transactions) or which
                contains transactions you do not want to retain, select
                the Clone option. The cluster then uses MySQL Clone to
                completely overwrite the joining instance with a
                snapshot from an donor cluster member. To use this
                method by default and disable this prompt, set the
                cluster's <code class="literal">recoveryMethod</code> option to
                <code class="literal">clone</code>.
              </p></li><li class="listitem"><p>
                <span class="emphasis"><em>Incremental recovery</em></span> choose this
                option to use incremental recovery to recover all
                transactions processed by the cluster to the joining
                instance using asynchronous replication. Incremental
                recovery is appropriate if you are sure all updates ever
                processed by the cluster were done with GTIDs enabled,
                there are no purged transactions and the new instance
                contains the same GTID set as the cluster or a subset of
                it. To use this method by default, set the
                <code class="literal">recoveryMethod</code> option to
                <code class="literal">incremental</code>.
</p></li></ul>
</div>
<p>
            The combination of factors mentioned influences which of
            these options is available at the prompt as follows:
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
              If the
              <a class="link" href="group-replication.html#sysvar_group_replication_clone_threshold"><code class="literal">group_replication_clone_threshold</code></a>
              system variable has been manually changed outside of
              AdminAPI, then the cluster might decide to use Clone
              recovery instead of following these scenarios.
</p>
</div>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
                In a scenario where
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                    incremental recovery is possible
                  </p></li><li class="listitem"><p>
                    incremental recovery is not appropriate
                  </p></li><li class="listitem"><p>
                    Clone is supported
</p></li></ul>
</div>
<p>
                you can choose between any of the options. It is
                recommended that you use MySQL Clone, the default.
              </p></li><li class="listitem"><p>
                In a scenario where
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                    incremental recovery is possible
                  </p></li><li class="listitem"><p>
                    incremental recovery is appropriate
</p></li></ul>
</div>
<p>
                you are not provided with the prompt, and incremental
                recovery is used.
              </p></li><li class="listitem"><p>
                In a scenario where
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                    incremental recovery is possible
                  </p></li><li class="listitem"><p>
                    incremental recovery is not appropriate
                  </p></li><li class="listitem"><p>
                    Clone is not supported or is disabled
</p></li></ul>
</div>
<p>
                you cannot use MySQL Clone to add the instance to the
                cluster. You are provided with the prompt, and the
                recommended option is to proceed with incremental
                recovery.
              </p></li><li class="listitem"><p>
                In a scenario where
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                    incremental recovery is not possible
                  </p></li><li class="listitem"><p>
                    Clone is not supported or is disabled
</p></li></ul>
</div>
<p>
                you cannot add the instance to the cluster and an
                <span class="errortext">ERROR: The target instance must be either
                cloned or fully provisioned before it can be added to
                the target cluster. Cluster.addInstance: Instance
                provisioning required (RuntimeError)</span> is
                shown. This could be the result of binary logs being
                purged from all cluster instances. It is recommended to
                use MySQL Clone, by either upgrading the cluster or
                setting the <code class="literal">disableClone</code> option to
                <code class="literal">false</code>.
              </p></li><li class="listitem"><p>
                In a scenario where
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                    incremental recovery is not possible
                  </p></li><li class="listitem"><p>
                    Clone is supported
</p></li></ul>
</div>
<p>
                you can only use MySQL Clone to add the instance to the
                cluster. This could be the result of the cluster missing
                binary logs, for example when they have been purged.
</p></li></ul>
</div>
<p>
            Once you select an option from the prompt, by default the
            progress of the instance recovering the transactions from
            the cluster is displayed. This monitoring enables you to
            check the recovery phase is working and also how long it
            should take for the instance to join the cluster and come
            online. To cancel the monitoring of the recovery phase,
            issue <span class="keycap"><strong>CONTROL+C</strong></span>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="innodb-cluster-clone-checkinstancestate"></a><code class="literal"><em class="replaceable"><code>Cluster</code></em>.checkInstanceState()</code>
and MySQL Clone</h5>
</div>
</div>
</div>
<p>
            When the
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.checkInstanceState()</code>
            operation is run to verify an instance against a cluster
            that is using MySQL Clone, if the instance does not have the
            binary logs, for example because they were purged but Clone
            is available and not disabled
            (<code class="literal">disableClone</code> is
            <code class="literal">false</code>) the operation provides a warning
            that the Clone can be used. For example:
          </p><pre class="programlisting">The cluster transactions cannot be recovered on the instance, however,
Clone is available and can be used when adding it to a cluster.

{
"reason": "all_purged", 
"state": "warning"
}</pre><p>
            Similarly, on an instance where Clone is either not
            available or has been disabled and the binary logs are not
            available, for example because they were purged, then the
            output includes:
          </p><pre class="programlisting">The cluster transactions cannot be recovered on the instance.

{
"reason": "all_purged", 
"state": "warning"
}</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h5 class="title"><a name="innodb-cluster-clone-checkinstanceconfiguration"></a><code class="literal">dba.checkInstanceConfiguration()</code> and MySQL Clone</h5>

</div>

</div>

</div>
<p>
            When the <code class="literal">dba.checkInstanceConfiguration()</code>
            operation is run against an instance that has MySQL Clone
            available but it is disabled, a warning is displayed.
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-sandbox-deployment"></a>21.2.6 Sandbox Deployment of InnoDB Cluster</h3>

</div>

</div>

</div>
<p>
        This section explains how to set up a sandbox InnoDB cluster
        deployment. You create and administer your InnoDB clusters using
        MySQL Shell with the included AdminAPI. This section assumes
        familiarity with MySQL Shell, see <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/" target="_top">MySQL Shell 8.0 (part of MySQL 8.0)</a>
        for further information.
      </p><p>
        Initially deploying and using local sandbox instances of MySQL
        is a good way to start your exploration of InnoDB cluster. You
        can fully test out InnoDB cluster locally, prior to deployment
        on your production servers. MySQL Shell has built-in
        functionality for creating sandbox instances that are correctly
        configured to work with Group Replication in a locally deployed
        scenario.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          Sandbox instances are only suitable for deploying and running
          on your local machine for testing purposes. In a production
          environment the MySQL Server instances are deployed to various
          host machines on the network. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-production-deployment" title="21.2.4 Production Deployment of InnoDB Cluster">Section 21.2.4, “Production Deployment of InnoDB Cluster”</a>
          for more information.
</p>
</div>
<p>
        This tutorial shows how to use MySQL Shell to create an
        InnoDB cluster consisting of three MySQL server instances. It
        consists of the following steps:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#deploy-sandbox-instances" title="Deploying Sandbox Instances">Deploying Sandbox Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#create-innodb-cluster" title="Creating the Sandbox InnoDB Cluster">Creating the Sandbox InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#add-instances-innodb-cluster" title="Adding Instances to an InnoDB Cluster">Adding Instances to an InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#persist-configuration-innodb-cluster" title="Persisting the Sandbox Configuration">Persisting the Sandbox Configuration</a></p></li></ul>
</div>

<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="deploy-sandbox-instances"></a>Deploying Sandbox Instances</h4>

</div>

</div>

</div>
<p>
          MySQL Shell includes the AdminAPI that adds the
          <code class="literal">dba</code> global variable, which provides
          functions for administration of sandbox instances. In this
          example setup, you create three sandbox instances using
          <code class="literal">dba.deploySandboxInstance()</code>.
        </p><p>
          Start MySQL Shell from a command prompt by issuing the
          command:
        </p><pre data-lang="terminal" class="programlisting">shell&gt; <strong class="userinput"><code>mysqlsh</code></strong>
</pre><p>
          MySQL Shell provides two scripting language modes, JavaScript
          and Python, in addition to a native SQL mode. Throughout this
          guide MySQL Shell is used primarily in JavaScript mode

          

          . When MySQL Shell starts it is in JavaScript mode by
          default. Switch modes by issuing <code class="literal">\js</code> for
          JavaScript mode, <code class="literal">\py</code> for Python mode, and
          <code class="literal">\sql</code> for SQL mode. Ensure you are in
          JavaScript mode by issuing the <code class="literal">\js</code> command,
          then execute:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(3310)</code></strong>
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
            Terminating commands with a semi-colon is not required in
            JavaScript and Python modes.
</p>
</div>
<p>
          The argument passed to
          <code class="literal">deploySandboxInstance()</code> is the TCP port
          number where the MySQL Server instance listens for
          connections. By default the sandbox is created in a directory
          named
          <code class="literal">$HOME/mysql-sandboxes/<em class="replaceable"><code>port</code></em></code>
          on Unix systems. For Microsoft Windows systems the directory
          is
          <code class="literal">%userprofile%\MySQL\mysql-sandboxes\<em class="replaceable"><code>port</code></em></code>.
        </p><p>
          The root user's password for the instance is prompted
          for.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
            Each sandbox instance uses the root user and password. This
            is not recommended in production, see
            <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-production-instances" title="Configuring Production Instances">Configuring Production Instances</a> for
            information about the <code class="literal">clusterAdmin</code>
            option.
</p>
</div>
<p>
          To deploy another sandbox server instance, repeat the steps
          followed for the sandbox instance at port 3310, choosing
          different port numbers for each instance. For each additional
          sandbox instance issue:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(<em class="replaceable"><code>port_number</code></em>)</code></strong>
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            The <code class="literal">clusterAdmin</code> user name and password
            must be the same on all instances that belong to a cluster.
            In the case of a sandbox deployment, the root user name and
            password must be the same on all instances.
</p>
</div>
<p>
          To follow this tutorial, use port numbers 3310, 3320 and 3330
          for the three sandbox server instances. Issue:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(<em class="replaceable"><code>3320</code></em>)</code></strong>
mysql-js&gt; <strong class="userinput"><code>dba.deploySandboxInstance(<em class="replaceable"><code>3330</code></em>)</code></strong>
</pre><p>
          To change the directory which sandboxes are stored in, for
          example to run multiple sandboxes on one host for testing
          purposes, use the MySQL Shell sandboxDir option. For example
          to use a sandbox in the <code class="literal">/home/user/sandbox1</code>
          directory, issue:
        </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>shell.options.sandboxDir='/home/user/sandbox1'</code></strong>
</pre><p>
          All subsequent sandbox related operations are then executed
          against the instances found at
          <code class="literal">/home/user/sandbox1</code>.
        </p><p>
          When you deploy sandboxes, MySQL Shell searches for the
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> binary which it then uses to create
          the sandbox instance. You can configure where MySQL Shell
          searches for the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> binary by
          configuring the <code class="literal">PATH</code> environment variable.
          This can be useful to test a new version of MySQL locally
          before deploying it to production. For example, to use a
          <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a> binary at the path
          <code class="filename">/home/user/mysql-latest/bin/mysqld</code> issue:
        </p><pre class="programlisting">PATH=/home/user/mysql-latest/bin/mysqld:$PATH</pre><p>
          Then run MySQL Shell from the terminal where the
          <code class="literal">PATH</code> environment variable is set. Any
          sandboxes you deploy then use the <a class="link" href="programs.html#mysqld" title="4.3.1 mysqld — The MySQL Server"><span class="command"><strong>mysqld</strong></span></a>
          binary found at the configured path.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="create-innodb-cluster"></a>Creating the Sandbox InnoDB Cluster</h4>

</div>

</div>

</div>
<p>
          The next step is to create the InnoDB cluster while
          connected to the seed MySQL Server instance. The seed instance
          contains the data that you want to replicate to the other
          instances. In this example the sandbox instances are blank,
          therefore we can choose any instance. Sandboxes also use MySQL
          Clone, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-clone-deployment" title="21.2.5 Using MySQL Clone with InnoDB cluster">Section 21.2.5, “Using MySQL Clone with InnoDB cluster”</a>.
        </p><p>
          Connect MySQL Shell to the seed instance, in this case the
          one at port 3310:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>\connect root@localhost:3310</code></strong></pre><p>
          The <code class="literal">\connect</code> MySQL Shell command is a
          shortcut for the <code class="literal">shell.connect()</code> method:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>shell.connect('root@localhost:3310')</code></strong>
</pre><p>
          Once you have connected, AdminAPI can write to the local
          instance's option file. This is different to working with
          a production deployment, where you would need to connect to
          the remote instance and run the MySQL Shell application
          locally on the instance before AdminAPI can write to the
          instance's option file.
        </p><p>
          Use the <code class="literal">dba.createCluster()</code> method to
          create the InnoDB cluster with the currently connected
          instance as the seed:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>var cluster = dba.createCluster('testCluster')</code></strong>
</pre><p>
          The <code class="literal">createCluster()</code> method deploys the
          InnoDB cluster metadata to the selected instance, and adds
          the instance you are currently connected to as the seed
          instance. The <code class="literal">createCluster()</code> method
          returns the created cluster, in the example above this is
          assigned to the <code class="literal">cluster</code> variable. The
          parameter passed to the <code class="literal">createCluster()</code>
          method is a symbolic name given to this InnoDB cluster, in
          this case <code class="literal">testCluster</code>.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            If the instance has
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
            might need to confirm that AdminAPI can set
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
            information.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="add-instances-innodb-cluster"></a>Adding Instances to an InnoDB Cluster</h4>

</div>

</div>

</div>
<p>
          The next step is to add more instances to the
          InnoDB cluster. Any transactions that were executed by the
          seed instance are re-executed by each secondary instance as it
          is added. This tutorial uses the sandbox instances that were
          created earlier at ports 3320 and 3330.
        </p><p>
          The seed instance in this example was recently created, so it
          is nearly empty. Therefore, there is little data that needs to
          be replicated from the seed instance to the secondary
          instances. In a production environment, where you have an
          existing database on the seed instance, you could use a tool
          such as MySQL Enterprise Backup to ensure that the secondaries have matching
          data before replication starts. This avoids the possibility of
          lengthy delays while data replicates from the primary to the
          secondaries. See
          <a class="xref" href="group-replication.html#group-replication-enterprise-backup" title="18.4.6 Using MySQL Enterprise Backup with Group Replication">Section 18.4.6, “Using MySQL Enterprise Backup with Group Replication”</a>.
        </p><p>
          Add the second instance to the InnoDB cluster:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.addInstance('root@localhost:3320')</code></strong>
</pre><p>
          The root user's password is prompted for. The specified
          instance is recovered from the seed instance. In other words
          the transactions from the seed are copied to the instance
          joining the cluster.
        </p><p>
          Add the third instance in the same way:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.addInstance('root@localhost:3330')</code></strong>
</pre><p>
          The root user's password is prompted for.
        </p><p>
          At this point you have created a cluster with three instances:
          a primary, and two secondaries.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            You can only specify <code class="literal">localhost</code> in
            <code class="literal">addInstance()</code> if the instance is a
            sandbox instance. This also applies to the implicit
            <code class="literal">addInstance()</code> after issuing
            <code class="literal">createCluster()</code>.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="persist-configuration-innodb-cluster"></a>Persisting the Sandbox Configuration</h4>

</div>

</div>

</div>
<p>
          Once the sandbox instances have been added to the cluster, the
          configuration required for InnoDB cluster must be persisted
          to each of the instance's option files. How you proceed
          depends on whether the instance supports persisting
          configuration changes automatically, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>.
          When the MySQL instance which you are using supports
          persisting configuration changes automatically, adding the
          instance automatically configures the instance. When the MySQL
          instance which you are using does not support persisting
          configuration changes automatically, you have to configure the
          instance locally. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-local-instances" title="Configuring Instances with dba.configureLocalInstance()">Configuring Instances with
        <code class="literal">dba.configureLocalInstance()</code></a>.
        </p><p>
          To check the cluster has been created, use the cluster
          instance's <code class="literal">status()</code> function. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking a cluster's Status with Cluster.status()">Checking a cluster's Status with
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code></a>.
        </p><p>
          Once you have your cluster deployed you can configure MySQL Router
          to provide high availability, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-using-router" title="21.4 Using MySQL Router with InnoDB Cluster">Section 21.4, “Using MySQL Router with InnoDB Cluster”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-from-group-replication"></a>21.2.7 Adopting a Group Replication Deployment</h3>

</div>

</div>

</div>
<p>
        If you have an existing deployment of Group Replication and you
        want to use it to create a cluster, pass the
        <code class="literal">adoptFromGR</code> option to the
        <code class="literal">dba.createCluster()</code> function. The created
        InnoDB cluster matches whether the replication group is
        running as single-primary or multi-primary.
      </p><p>
        To adopt an existing Group Replication group, connect to a group
        member using MySQL Shell. In the following example a
        single-primary group is adopted. We connect to
        <code class="literal">gr-member-2</code>, a secondary instance, while
        <code class="literal">gr-member-1</code> is functioning as the group's
        primary. Create a cluster using
        <code class="literal">dba.createCluster()</code>, passing in the
        <code class="literal">adoptFromGR</code> option. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">  
mysql-js&gt; <strong class="userinput"><code>var cluster = dba.createCluster('prodCluster', {adoptFromGR: true});</code></strong>

A new InnoDB cluster will be created on instance 'root@gr-member-2:3306'.

Creating InnoDB cluster 'prodCluster' on 'root@gr-member-2:3306'...
Adding Seed Instance...

Cluster successfully created. Use cluster.addInstance() to add MySQL instances.
At least 3 instances are needed for the cluster to be able to withstand up to
one server failure.
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          If the instance has
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
          might need to confirm that AdminAPI can set
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
          information.
</p>
</div>
<p>
        The new cluster matches the mode of the group. If the adopted
        group was running in single-primary mode then a single-primary
        cluster is created. If the adopted group was running in
        multi-primary mode then a multi-primary cluster is created.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-upgrade"></a>21.3 Upgrading an InnoDB cluster</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade-rolling">21.3.1 Rolling Upgrades</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade-metadata">21.3.2 Upgrading InnoDB cluster Metadata</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade-troubleshoot">21.3.3 Troubleshooting InnoDB cluster Upgrades</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444251109280"></a><p>
      This section explains how to upgrade your cluster. Much of the
      process of upgrading an InnoDB cluster consists of upgrading the
      instances in the same way as documented at
      <a class="xref" href="group-replication.html#group-replication-upgrade" title="18.7 Upgrading Group Replication">Section 18.7, “Upgrading Group Replication”</a>. This section focuses
      on the additional considerations for upgrading InnoDB cluster.
      Before starting an upgrade, you can use the MySQL Shell
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-upgrade.html" target="_top">Upgrade Checker Utility</a> to verify
      instances are ready for the upgrade.

      
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-upgrade-rolling"></a>21.3.1 Rolling Upgrades</h3>
</div>
</div>
</div>
<p>
        When upgrading the metadata schema of clusters deployed by
        MySQL Shell versions before 8.0.19, a rolling upgrade of
        existing MySQL Router instances is required. This process minimizes
        disruption to applications during the upgrade. The rolling
        upgrade process must be performed in the following order:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
            Run the latest MySQL Shell version, connect the global
            session to the cluster and issue
            <code class="literal">dba.upgradeMetadata()</code>. The upgrade
            function stops if an outdated MySQL Router instance is detected,
            at which point you can stop the upgrade process in
            MySQL Shell to resume later.
          </p></li><li class="listitem"><p>
            Upgrade any detected out of date MySQL Router instances to the
            latest version. It is recommended to use the same MySQL Router
            version as MySQL Shell version.

            
          </p></li><li class="listitem"><p>
            Continue or restart the
            <code class="literal">dba.upgradeMetadata()</code> operation to
            complete the metadata upgrade.
</p></li></ol>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-upgrade-metadata"></a>21.3.2 Upgrading InnoDB cluster Metadata</h3>

</div>

</div>

</div>
<p>
        As AdminAPI evolves, some releases might require you to
        upgrade the metadata of existing clusters to ensure they are
        compatible with newer versions of MySQL Shell. For example, the
        addition of InnoDB ReplicaSet in version 8.0.19 means that the
        metadata schema has been upgraded to version 2.0. Regardless of
        whether you plan to use InnoDB ReplicaSet or not, to use
        MySQL Shell 8.0.19 or later with a cluster deployed using an
        earlier version of MySQL Shell, you must upgrade the metadata
        of your cluster.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          Without upgrading the metadata you cannot use MySQL Shell
          8.0.19 to change the configuration of a cluster created with
          earlier versions. For example, you can only perform read
          operations against the cluster such as
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>,
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.describe()</code>,
          and
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.options()</code>.
</p>
</div>
<p>
        This <code class="literal">dba.upgradeMetadata()</code> operation compares
        the version of the metadata schema found on the cluster
        MySQL Shell is currently connected to with the version of the
        metadata schema supported by this MySQL Shell version. If the
        installed metadata version is lower, an upgrade process is
        started. The <code class="literal">dba.upgradeMetadata()</code> operation
        then upgrades any automatically created MySQL Router users to have
        the correct privileges. Manually created MySQL Router users with a
        name not starting with <code class="literal">mysql_router_</code> are not
        automatically upgraded. This is an important step in upgrading
        your cluster, only then can the MySQL Router application be
        upgraded. To get information on which of the MySQL Router instances
        registered with a cluster require the metadata upgrade, issue:
      </p><pre class="programlisting">cluster.listRouters({'onlyUpgradeRequired':'true'})
{
    "clusterName": "mycluster", 
    "routers": {
        "example.com::": {
            "hostname": "example.com", 
            "lastCheckIn": "2019-11-26 10:10:37", 
            "roPort": 6447, 
            "roXPort": 64470, 
            "rwPort": 6446, 
            "rwXPort": 64460, 
            "version": "8.0.18"
        }
    }
}</pre>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          A cluster which is using the new metadata cannot be
          administered by earlier MySQL Shell versions, for example
          once you upgrade to version 8.0.19 you can no longer use
          version 8.0.18 or earlier to administer the cluster.
</p>
</div>
<p>
        To upgrade a cluster's metadata, connect MySQL Shell's global
        session to your cluster and use the
        <code class="literal">dba.upgradeMetadata()</code> operation to upgrade
        the cluster's metadata to the new metadata. For example:
      </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>\connect user@example.com:3306</code></strong>

mysql-js&gt; <strong class="userinput"><code>dba.upgradeMetadata()</code></strong>
InnoDB Cluster Metadata Upgrade

The cluster you are connected to is using an outdated metadata schema version
1.0.1 and needs to be upgraded to 2.0.0.

Without doing this upgrade, no AdminAPI calls except read only operations will
be allowed.

The grants for the MySQL Router accounts that were created automatically when
bootstrapping need to be updated to match the new metadata version's
requirements.
Updating router accounts...
NOTE: 2 router accounts have been updated.

Upgrading metadata at 'example.com:3306' from version 1.0.1 to version 2.0.0.
Creating backup of the metadata schema...
Step 1 of 1: upgrading from 1.0.1 to 2.0.0...
Removing metadata backup...
Upgrade process successfully finished, metadata schema is now on version 2.0.0
</pre><p>
        If you encounter an error related to the
        <code class="literal">clusterAdmin</code> user missing privileges, follow
        the instructions for granting the correct privileges.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-cluster-upgrade-troubleshoot"></a>21.3.3 Troubleshooting InnoDB cluster Upgrades</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444251077232"></a><p>
        This section covers trouble shooting the upgrade process.

        
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="handling-host-name-changes"></a>Handling Host Name Changes</h4>
</div>
</div>
</div>
<p>
          MySQL Shell uses the host value of the provided connection
          parameters as the target hostname used for AdminAPI
          operations, namely to register the instance in the metadata
          (for the <code class="literal">dba.createCluster()</code> and
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
          operations). However, the actual host used for the connection
          parameters might not match the
          <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> that is used or
          reported by Group Replication, which uses the value of the
          <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a> system variable
          when it is defined (in other words it is not
          <code class="literal">NULL</code>), otherwise the value of
          <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> is used. Therefore,
          AdminAPI now follows the same logic to register the target
          instance in the metadata and as the default value for the
          <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
          variable on instances, instead of using the host value from
          the instance connection parameters. When the
          <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a> variable is set
          to empty, Group Replication uses an empty value for the host
          but AdminAPI (for example in commands such as
          <code class="literal">dba.checkInstanceConfiguration()</code>,
          <code class="literal">dba.configureInstance()</code>,
          <code class="literal">dba.createCluster()</code>, and so on) reports the
          hostname as the value used which is inconsistent with the
          value reported by Group Replication. If an empty value is set
          for the <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a> system
          variable, an error is generated. (Bug #28285389)
        </p><p>
          For a cluster created using a MySQL Shell version earlier than
          8.0.16, an attempt to reboot the cluster from a complete
          outage performed using version 8.0.16 or higher results in
          this error. This is caused by a mismatch of the Metadata
          values with the <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a>
          or <a class="link" href="server-administration.html#sysvar_hostname"><code class="literal">hostname</code></a> values reported
          by the instances. The workaround is to:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              Identify which of the instances is the
              <span class="quote">“<span class="quote">seed</span>”</span>, in other words the one with the most
              recent GTID set. The
              <code class="literal">dba.rebootClusterFromCompleteOutage()</code>
              operation detects whether the instance is a seed and the
              operation generates an error if the current session is not
              connected to the most up-to-date instance.
            </p></li><li class="listitem"><p>
              Set the <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a>
              system variable to the value that is stored in the
              Metadata schema for the target instance. This value is the
              <code class="literal">hostname:port</code> pair used in the instance
              definition upon cluster creation. The value can be
              consulted by querying the
              <code class="literal">mysql_innodb_cluster_metadata.instances</code>
              table.
            </p><p>
              For example, suppose a cluster was created using the
              following sequence of commands:
            </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>\c clusterAdmin@localhost:3306</code></strong>
mysql-js&gt; <strong class="userinput"><code>dba.createCluster("myCluster")</code></strong>
</pre><p>
              Therefore the hostname value stored in the metadata is
              <span class="quote">“<span class="quote">localhost</span>”</span> and for that reason,
              <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a> must be set
              to <span class="quote">“<span class="quote">localhost</span>”</span> on the seed.
            </p></li><li class="listitem"><p>
              Reboot the cluster using only the seed instance. At the
              interactive prompts do not add the remaining instances to
              the cluster.
            </p></li><li class="listitem"><p>
              Use
              <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan()</code>
              to add the other instances back to the cluster.
            </p></li><li class="listitem"><p>
              Remove the seed instance from the cluster
            </p></li><li class="listitem"><p>
              Stop mysqld on the seed instance and either remove the
              forced <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a>
              setting (step 2), or replace it with the value previously
              stored in the Metadata value.
            </p></li><li class="listitem"><p>
              Restart the seed instance and add it back to the cluster
              using
              <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
</p></li></ol>
</div>
<p>
          This allows a smooth and complete upgrade of the cluster to
          the latest MySQL Shell version. Another possibility, that
          depends on the use-case, is to simply set the value of
          <a class="link" href="replication.html#sysvar_report_host"><code class="literal">report_host</code></a> on all cluster
          members to match what has been registered in the Metadata
          schema upon cluster creation.
</p>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-using-router"></a>21.4 Using MySQL Router with InnoDB Cluster</h2>

</div>

</div>

</div>
<a class="indexterm" name="idm46444251032656"></a><p>
      This section describes how to use MySQL Router with InnoDB cluster
      to achieve high availability. Regardless of whether you have
      deployed a sandbox or production cluster, MySQL Router can configure
      itself based on the InnoDB cluster's metadata using the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option. This
      configures MySQL Router automatically to route connections to the
      cluster's server instances. Client applications connect to
      the ports MySQL Router provides, without any need to be aware of the
      InnoDB cluster topology. In the event of a unexpected failure,
      the InnoDB cluster adjusts itself automatically and MySQL Router
      detects the change. This removes the need for your client
      application to handle failover. For more information, see
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-innodb-cluster.html" target="_top">Routing for MySQL InnoDB cluster</a>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
        Do not attempt to configure MySQL Router manually to redirect to the
        ports of an InnoDB cluster. Always use the
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option as this
        ensures that MySQL Router takes its configuration from the
        InnoDB cluster's metadata. See
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-general-metadata.html" target="_top">Cluster Metadata and State</a>.
</p>
</div>
<p>
      The recommended deployment of MySQL Router is on the same host as the
      application. When using a sandbox deployment, everything is
      running on a single host, therefore you deploy MySQL Router to the
      same host. When using a production deployment, we recommend
      deploying one MySQL Router instance to each machine used to host one
      of your client applications. It is also possible to deploy
      MySQL Router to a common machine through which your application
      instances connect.
    </p><p>
      Assuming MySQL Router is already installed (see
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-installation.html" target="_top">Installing MySQL Router</a>), use the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option to provide
      the location of a server instance that belongs to the
      InnoDB cluster. MySQL Router uses the included metadata cache plugin
      to retrieve the InnoDB cluster's metadata, consisting of a
      list of server instance addresses which make up the
      InnoDB cluster and their role in the cluster. You pass the
      URI-like connection string of the server that MySQL Router should
      retrieve the InnoDB cluster metadata from. For example:
    </p><pre data-lang="terminal" class="programlisting">shell&gt; <strong class="userinput"><code>mysqlrouter --bootstrap icadmin@ic-1:3306 --user=mysqlrouter </code></strong>
</pre><p>
      You are prompted for the instance password and encryption key for
      MySQL Router to use. This encryption key is used to encrypt the
      instance password used by MySQL Router to connect to the cluster. The
      ports you can use to connect to the InnoDB cluster are also
      displayed. The MySQL Router bootstrap process creates a
      <code class="filename">mysqlrouter.conf</code> file, with the settings
      based on the cluster metadata retrieved from the address passed to
      the <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option, in the
      above example <code class="literal">icadmin@ic-1:3306</code>. Based on the
      InnoDB cluster metadata retrieved, MySQL Router automatically
      configures the <code class="filename">mysqlrouter.conf</code> file,
      including a <code class="literal">metadata_cache</code> section. If you are
      using MySQL Router 8.0.14 and later, the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option
      automatically configures MySQL Router to track and store active MySQL
      InnoDB cluster Metadata server addresses at the path configured
      by <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_dynamic_state" target="_top"><code class="option">dynamic_state</code></a>. This ensures
      that when MySQL Router is restarted it knows which MySQL
      InnoDB cluster Metadata server addresses are current. For more
      information see the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_dynamic_state" target="_top"><code class="option">dynamic_state</code></a> documentation.
    </p><p>
      In earlier MySQL Router versions, metadata server information was
      defined during Router's initial bootstrap operation and stored
      statically as
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_bootstrap_server_addresses" target="_top"><code class="option">bootstrap_server_addresses</code></a> in
      the configuration file, which contained the addresses for all
      server instances in the cluster. For example:
    </p><pre data-lang="ini" class="programlisting">[metadata_cache:prodCluster]
router_id=1
bootstrap_server_addresses=mysql://icadmin@ic-1:3306,mysql://icadmin@ic-2:3306,mysql://icadmin@ic-3:3306
user=mysql_router1_jy95yozko3k2
metadata_cluster=prodCluster
ttl=300</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
        If using MySQL Router 8.0.13 or earlier, when you change the
        topology of a cluster by adding another server instance after
        you have bootstrapped MySQL Router, you need to update
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_bootstrap_server_addresses" target="_top"><code class="option">bootstrap_server_addresses</code></a>
        based on the updated metadata. Either restart MySQL Router using the
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option, or
        manually edit the
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_bootstrap_server_addresses" target="_top"><code class="option">bootstrap_server_addresses</code></a>
        section of the <code class="filename">mysqlrouter.conf</code> file and
        restart MySQL Router.
</p>
</div>
<p>
      The generated MySQL Router configuration creates TCP ports which you
      use to connect to the cluster. By default, ports for communicating
      with the cluster using both classic MySQL protocol and X Protocol are
      created. To use X Protocol the server instances must have
      X Plugin installed and configured, which is the default for MySQL
      8.0 and later. The default available TCP ports are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          <code class="literal">6446</code> - for classic MySQL protocol read-write
          sessions, which MySQL Router redirects incoming connections to
          primary server instances.
        </p></li><li class="listitem"><p>
          <code class="literal">6447</code> - for classic MySQL protocol read-only
          sessions, which MySQL Router redirects incoming connections to one
          of the secondary server instances.
        </p></li><li class="listitem"><p>
          <code class="literal">64460</code> - for X Protocol read-write
          sessions, which MySQL Router redirects incoming connections to
          primary server instances.
        </p></li><li class="listitem"><p>
          <code class="literal">64470</code> - for X Protocol read-only sessions,
          which MySQL Router redirects incoming connections to one of the
          secondary server instances.
</p></li></ul>
</div>
<p>
      Depending on your MySQL Router configuration the port numbers might be
      different to the above. For example if you use the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_conf-base-port" target="_top"><code class="option">--conf-base-port</code></a> option, or
      the
      <a class="link" href="group-replication.html#sysvar_group_replication_single_primary_mode"><code class="literal">group_replication_single_primary_mode</code></a>
      variable. The exact ports are listed when you start MySQL Router.
    </p><p>
      The way incoming connections are redirected depends on the type of
      cluster being used. When using a single-primary cluster, by
      default MySQL Router publishes a X Protocol and a classic MySQL protocol
      port, which clients connect to for read-write sessions and which
      are redirected to the cluster's single primary. With a
      multi-primary cluster read-write sessions are redirected to one of
      the primary instances in a round-robin fashion. For example, this
      means that the first connection to port 6446 would be redirected
      to the ic-1 instance, the second connection to port 6446 would be
      redirected to the ic-2 instance, and so on. For incoming read-only
      connections MySQL Router redirects connections to one of the secondary
      instances, also in a round-robin fashion. To modify this behavior
      see the <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_routing_strategy" target="_top"><code class="option">routing_strategy</code></a>
      option.
    </p><p>
      Once bootstrapped and configured, start MySQL Router. If you used a
      system wide install with the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option then issue:
    </p><pre data-lang="terminal" class="programlisting">shell&gt; <strong class="userinput"><code>mysqlrouter &amp;</code></strong>
</pre><p>
      If you installed MySQL Router to a directory using the
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_directory" target="_top"><code class="option">--directory</code></a> option, use the
      <code class="filename">start.sh</code> script found in the directory you
      installed to. Alternatively set up a service to start MySQL Router
      automatically when the system boots, see
      <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-server-starting.html" target="_top">Starting MySQL Router</a>. You can now
      connect a MySQL client, such as MySQL Shell to one of the
      incoming MySQL Router ports as described above and see how the client
      gets transparently connected to one of the InnoDB cluster
      instances.
    </p><pre data-lang="terminal" class="programlisting">shell&gt; <strong class="userinput"><code>mysqlsh --uri root@localhost:6442</code></strong>
</pre><p>
      To verify which instance you are actually connected to, simply
      issue an SQL query against the
      <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> status variable.

      
    </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>\sql</code></strong>
Switching to SQL mode... Commands end with ;
mysql-sql&gt; <strong class="userinput"><code>select @@port;</code></strong>
+--------+
| @@port |
+--------+
|   3310 |
+--------+
</pre>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h3 class="title"><a name="test-failover"></a>Testing High Availability</h3>
</div>
</div>
</div>
<p>
        To test if high availability works, simulate an unexpected halt
        by killing an instance. The cluster detects the fact that the
        instance left the cluster and reconfigures itself. Exactly how
        the cluster reconfigures itself depends on whether you are using
        a single-primary or multi-primary cluster, and the role the
        instance serves within the cluster.
      </p><p>
        In single-primary mode:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            If the current primary leaves the cluster, one of the
            secondary instances is elected as the new primary, with
            instances prioritized by the lowest
            <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a>. MySQL Router
            redirects read-write connections to the newly elected
            primary.
          </p></li><li class="listitem"><p>
            If a current secondary leaves the cluster, MySQL Router stops
            redirecting read-only connections to the instance.
</p></li></ul>
</div>
<p>
        For more information see
        <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="18.1.3.1 Single-Primary Mode">Section 18.1.3.1, “Single-Primary Mode”</a>.
      </p><p>
        In multi-primary mode:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            If a current "R/W" instance leaves the cluster, MySQL Router
            redirects read-write connections to other primaries. If the
            instance which left was the last primary in the cluster then
            the cluster is completely gone and you cannot connect to any
            MySQL Router port.
</p></li></ul>
</div>
<p>
        For more information see
        <a class="xref" href="group-replication.html#group-replication-multi-primary-mode" title="18.1.3.2 Multi-Primary Mode">Section 18.1.3.2, “Multi-Primary Mode”</a>.
      </p><p>
        There are various ways to simulate an instance leaving a
        cluster, for example you can forcibly stop the MySQL server on
        an instance, or use the AdminAPI
        <code class="literal">dba.killSandboxInstance()</code> if testing a
        sandbox deployment. In this example assume there is a
        single-primary sandbox cluster deployment with three server
        instances and the instance listening at port 3310 is the current
        primary. Simulate the instance leaving the cluster unexpectedly:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>dba.killSandboxInstance(3310)</code></strong>
</pre><p>
        The cluster detects the change and elects a new primary
        automatically. Assuming your session is connected to port 6446,
        the default read-write classic MySQL protocol port, MySQL Router should
        detect the change to the cluster's topology and redirect your
        session to the newly elected primary. To verify this, switch to
        SQL mode in MySQL Shell using the <code class="literal">\sql</code>
        command and select the instance's
        <a class="link" href="server-administration.html#sysvar_port"><code class="literal">port</code></a> variable to check which
        instance your session has been redirected to. Notice that the
        first <a class="link" href="sql-statements.html#select" title="13.2.10 SELECT Statement"><code class="literal">SELECT</code></a> statement fails as
        the connection to the original primary was lost. This means the
        current session has been closed, MySQL Shell automatically
        reconnects for you and when you issue the command again the new
        port is confirmed.
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>\sql</code></strong>
Switching to SQL mode... Commands end with ;
mysql-sql&gt; <strong class="userinput"><code>SELECT @@port;</code></strong>
ERROR: 2013 (HY000): Lost connection to MySQL server during query
The global session got disconnected.
Attempting to reconnect to 'root@localhost:6446'...
The global session was successfully reconnected.
mysql-sql&gt; <strong class="userinput"><code>SELECT @@port;</code></strong>
+--------+
| @@port |
+--------+
|   3330 |
+--------+
1 row in set (0.00 sec)
</pre><p>
        In this example, the instance at port 3330 has been elected as
        the new primary. This shows that the InnoDB cluster provided
        us with automatic failover, that MySQL Router has automatically
        reconnected us to the new primary instance, and that we have
        high availability.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="router-and-metadata-servers"></a>MySQL Router and Metadata Servers</h3>

</div>

</div>

</div>
<p>
        When MySQL Router is bootstrapped against a cluster, it records the
        server instance's addresses in its configuration file. If
        any additional instances are added to the cluster after
        bootstrapping the MySQL Router, they are not automatically detected
        and therefore are <span class="emphasis"><em>not</em></span> used for connection
        routing.
      </p><p>
        To ensure that newly added instances are routed to correctly you
        must bootstrap MySQL Router against the cluster to read the updated
        metadata. This means that you must restart MySQL Router and include
        the <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysqlrouter.html#option_mysqlrouter_bootstrap" target="_top"><code class="option">--bootstrap</code></a> option.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="registered-routers"></a>Working with a Cluster's Routers</h3>

</div>

</div>

</div>
<p>
        You can bootstrap multiple instances of MySQL Router against a
        cluster or replica set. From version 8.0.19, to show a list of
        all registered MySQL Router instances, issue:
      </p><pre class="programlisting"><strong class="userinput"><code><em class="replaceable"><code>Cluster</code></em>.listRouters()</code></strong></pre><p>
        The result provides information about each registered MySQL Router
        instance, such as its name in the metadata, the hostname, ports,
        and so on. For example, issue:
      </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>Cluster.listRouters()</code></strong>
{
    "clusterName": "example", 
    "routers": {
        "ic-1:3306": {
            "hostname": "ic-1:3306", 
            "lastCheckIn": "2020-01-16 11:43:45", 
            "roPort": 6447, 
            "roXPort": 64470, 
            "rwPort": 6446, 
            "rwXPort": 64460, 
            "version": "8.0.19"
        }
    }
}
</pre><p>
        The returned information shows:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            The name of the MySQL Router instance.
          </p></li><li class="listitem"><p>
            Last check-in timestamp, which is generated by a periodic
            ping from the MySQL Router stored in the metadata
          </p></li><li class="listitem"><p>
            Hostname where the MySQL Router instance is running
          </p></li><li class="listitem"><p>
            Read-Only and Read-Write ports which the MySQL Router publishes
            for classic MySQL protocol connections
          </p></li><li class="listitem"><p>
            Read-Only and Read-Write ports which the MySQL Router publishes
            for X Protocol connections
          </p></li><li class="listitem"><p>
            Version of this MySQL Router instance. The support for returning
            <code class="literal">version</code> was added in 8.0.19. If this
            operation is run against an earlier version of MySQL Router, the
            version field is <code class="literal">null</code>.
</p></li></ul>
</div>
<p>
        Additionally, the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.listRouters()</code>
        operation can show a list of instances that do not support the
        metadata version supported by MySQL Shell. Use the
        <code class="literal">onlyUpgradeRequired</code> option, for example by
        issuing
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.listRouters({'onlyUpgradeRequired':'true'})</code>.
        The returned list shows only the MySQL Router instances registered
        with the <em class="replaceable"><code>Cluster</code></em> which require an
        upgrade of their metadata. See
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-upgrade-metadata" title="21.3.2 Upgrading InnoDB cluster Metadata">Section 21.3.2, “Upgrading InnoDB cluster Metadata”</a>.
      </p><p>
        MySQL Router instances are not automatically removed from the
        metadata, so for example as you bootstrap more instances the
        InnoDB cluster metadata contains a growing number of
        references to instances. To remove a registered MySQL Router
        instance from a cluster's metadata, use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.removeRouterMetadata(<em class="replaceable"><code>router</code></em>)</code>
        operation, added in version 8.0.19. Use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.listRouters()</code>
        operation to get the name of the MySQL Router instance you want to
        remove, and pass it in as <em class="replaceable"><code>router</code></em>. For
        example suppose your MySQL Router instances registered with a
        cluster were:
      </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code><em class="replaceable"><code>Cluster</code></em>.listRouters()</code></strong>{

    "clusterName": "testCluster",
    "routers": {
        "myRouter1": {
            "hostname": "example1.com",
            "lastCheckIn": null,
            "routerId": "1",
            "roPort": "6447",
            "rwPort": "6446"
            "version": null
        },
        "myRouter2": {
            "hostname": "example2.com",
            "lastCheckIn": "2019-11-27 16:25:00",
            "routerId": "3",
            "roPort": "6447",
            "rwPort": "6446"
            "version": "8.0.19"
        }
    }
}
</pre><p>
        Based on the fact that the instance named
        <span class="quote">“<span class="quote">myRouter1</span>”</span> has <code class="literal">null</code> for
        <span class="quote">“<span class="quote">lastCheckIn</span>”</span> and <span class="quote">“<span class="quote">version</span>”</span>, we decide
        to remove this old instance from the metadata by issuing:
      </p><pre class="programlisting">mysql-js&gt; cluster.removeRouterMetadata('myRouter1')</pre><p>
        The MySQL Router instance specified is unregistered from the cluster
        by removing it from the InnoDB cluster metadata.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-working-with-cluster"></a>21.5 Working with InnoDB Cluster</h2>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250920800"></a><p>
      This section explains how to work with InnoDB cluster, and how
      to handle common administration tasks.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#check-instance-configuration" title="Using dba.checkInstanceConfiguration()">Using <code class="literal">dba.checkInstanceConfiguration()</code></a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-local-instances" title="Configuring Instances with dba.configureLocalInstance()">Configuring Instances with
        <code class="literal">dba.configureLocalInstance()</code></a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#retrieving-an-innodb-cluster" title="Retrieving an InnoDB cluster with dba.getCluster()">Retrieving an InnoDB cluster with <code class="literal">dba.getCluster()</code></a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#connect-primary-innodb-cluster" title="Finding the Primary">Finding the Primary</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#describe-structure-innodb-cluster" title="Using cluster.describe()">Using <code class="literal">cluster.describe()</code></a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking a cluster's Status with Cluster.status()">Checking a cluster's Status with
<code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code></a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#innodb-cluster-monitoring-recovery" title="Monitoring Recovery Operations">Monitoring Recovery Operations</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#innodb-cluster-group-replication-protocol" title="InnoDB cluster and Group Replication Protocol">InnoDB cluster and Group Replication Protocol</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#checking-version-on-instances" title="Checking the MySQL Version on Instances">Checking the MySQL Version on Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#configure-innodb-cluster-user" title="Configuring Users for InnoDB Cluster">Configuring Users for InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-automatic-rejoin-of-instances" title="Configuring Automatic Rejoin of Instances">Configuring Automatic Rejoin of Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#manage-sandbox-instances" title="Managing Sandbox Instances">Managing Sandbox Instances</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#innodb-cluster-binary-log-purging" title="InnoDB Cluster and Binary Log Purging">InnoDB Cluster and Binary Log Purging</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#remove-instances-from-innodb-cluster" title="Removing Instances from the InnoDB Cluster">Removing Instances from the InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#customize-your-cluster" title="Customizing InnoDB clusters">Customizing InnoDB clusters</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#rejoin-cluster" title="Rejoining a Cluster">Rejoining a Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#restore-cluster-from-quorum-loss" title="Restoring a Cluster from Quorum Loss">Restoring a Cluster from Quorum Loss</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#reboot-outage" title="Rebooting a Cluster from a Major Outage">Rebooting a Cluster from a Major Outage</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#rescan-cluster" title="Rescanning a Cluster">Rescanning a Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#check-instance-state" title="Checking Instance State">Checking Instance State</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#dissolve-innodb-cluster" title="Dissolving an InnoDB Cluster">Dissolving an InnoDB Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-securing" title="Securing your Cluster">Securing your Cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#create-whitelist-servers" title="Creating a Whitelist of Servers">Creating a Whitelist of Servers</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#use-mysql-shell-execute-script" title="Scripting AdminAPI">Scripting AdminAPI</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-election-process" title="Configuring the Election Process">Configuring the Election Process</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-failover-consistency" title="Configuring Failover Consistency">Configuring Failover Consistency</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-change-topology" title="Changing a Cluster's Topology">Changing a Cluster's Topology</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-setting-options" title="Setting Options for InnoDB cluster">Setting Options for InnoDB cluster</a></p></li><li class="listitem"><p><a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-auto-increment" title="InnoDB cluster and Auto-increment">InnoDB cluster and Auto-increment</a></p></li></ul>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="check-instance-configuration"></a>Using <code class="literal">dba.checkInstanceConfiguration()</code></h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250885344"></a><a class="indexterm" name="idm46444250883840"></a><p>
        Before creating a production deployment from server instances
        you need to check that MySQL on each instance is correctly
        configured. In addition to
        <code class="literal">dba.configureInstance()</code>, which checks the
        configuration as part of configuring an instance, you can use
        the <code class="literal">dba.checkInstanceConfiguration()</code>
        function. This ensures that the instance satisfies the
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-requirements" title="21.2.2 InnoDB Cluster Requirements">Section 21.2.2, “InnoDB Cluster Requirements”</a> without
        changing any configuration on the instance. This does not check
        any data that is on the instance, see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#check-instance-state" title="Checking Instance State">Checking Instance State</a> for more information. The
        following demonstrates issuing this in a running MySQL Shell:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>dba.checkInstanceConfiguration('icadmin@ic-1:3306')</code></strong>
Please provide the password for 'icadmin@ic-1:3306': ***
Validating MySQL instance at ic-1:3306 for use in an InnoDB cluster...

This instance reports its own address as ic-1
Clients and other cluster members will communicate with it through this address by default.
If this is not correct, the report_host MySQL system variable should be changed.

Checking whether existing tables comply with Group Replication requirements...
No incompatible tables detected

Checking instance configuration...

Some configuration options need to be fixed:
+--------------------------+---------------+----------------+--------------------------------------------------+
| Variable                 | Current Value | Required Value | Note                                             |
+--------------------------+---------------+----------------+--------------------------------------------------+
| binlog_checksum          | CRC32         | NONE           | Update the server variable                       |
| enforce_gtid_consistency | OFF           | ON             | Update read-only variable and restart the server |
| gtid_mode                | OFF           | ON             | Update read-only variable and restart the server |
| server_id                | 1             |                | Update read-only variable and restart the server |
+--------------------------+---------------+----------------+--------------------------------------------------+

Please use the dba.configureInstance() command to repair these issues.

{
    "config_errors": [
        {
            "action": "server_update",
            "current": "CRC32",
            "option": "binlog_checksum",
            "required": "NONE"
        },
        {
            "action": "restart",
            "current": "OFF",
            "option": "enforce_gtid_consistency",
            "required": "ON"
        },
        {
            "action": "restart",
            "current": "OFF",
            "option": "gtid_mode",
            "required": "ON"
        },
        {
            "action": "restart",
            "current": "1",
            "option": "server_id",
            "required": ""
        }
    ],
    "status": "error"
}
</pre><p>
        Repeat this process for each server instance that you plan to
        use as part of your cluster. The report generated after running
        <code class="literal">dba.checkInstanceConfiguration()</code> provides
        information about any configuration changes required before you
        can proceed. The <code class="literal">action</code> field in the
        <code class="literal">config_error</code> section of the report tells you
        whether MySQL on the instance requires a restart to detect any
        change made to the configuration file.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="configuring-local-instances"></a>Configuring Instances with
<code class="literal">dba.configureLocalInstance()</code></h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444250867632"></a><a class="indexterm" name="idm46444250866128"></a><p>
        Instances which do not support persisting configuration changes
        automatically (see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>)
        require you to connect to the server, run MySQL Shell, connect
        to the instance locally and issue
        <code class="literal">dba.configureLocalInstance()</code>. This enables
        MySQL Shell to modify the instance's option file after running
        the following commands against a remote instance:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">dba.configureInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">dba.createCluster()</code>
          </p></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.removeInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rejoinInstance()</code>
</p></li></ul>
</div>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Important
</div>
<p>
          Failing to persist configuration changes to an instance's
          option file can result in the instance not rejoining the
          cluster after the next restart.
</p>
</div>
<p>
        The recommended method is to log in to the remote machine, for
        example using SSH, run MySQL Shell as the root user and then
        connect to the local MySQL server. For example, use the
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysqlsh.html#option_mysqlsh_uri" target="_top"><code class="option">--uri</code></a> option to connect to the
        local <em class="replaceable"><code>instance</code></em>:
      </p><pre data-lang="terminal" class="programlisting">shell&gt; <strong class="userinput"><code>sudo -i mysqlsh --uri=<em class="replaceable"><code>instance</code></em></code></strong>
</pre><p>
        Alternatively use the <code class="literal">\connect</code> command to log
        in to the local instance. Then issue
        <code class="literal">dba.configureInstance(<em class="replaceable"><code>instance</code></em>)</code>,
        where <em class="replaceable"><code>instance</code></em> is the connection
        information to the local instance, to persist any changes made
        to the local instance's option file.
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; dba.configureLocalInstance('icadmin@ic-2:3306')
	</pre><p>
        Repeat this process for each instance in the cluster which does
        not support persisting configuration changes automatically. For
        example if you add 2 instances to a cluster which do not support
        persisting configuration changes automatically, you must connect
        to each server and persist the configuration changes required
        for InnoDB cluster before the instance restarts. Similarly if
        you modify the cluster structure, for example changing the
        number of instances, you need to repeat this process for each
        server instance to update the InnoDB cluster metadata
        accordingly for each instance in the cluster.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="retrieving-an-innodb-cluster"></a>Retrieving an InnoDB cluster with <code class="literal">dba.getCluster()</code></h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250842032"></a><a class="indexterm" name="idm46444250840544"></a><p>
        When you create a cluster using
        <code class="literal">dba.createCluster()</code>, the operation returns a
        Cluster object which can be assigned to a variable. You use this
        object to work with the cluster, for example to add instances or
        check the cluster's status. If you want to retrieve a cluster
        again at a later date, for example after restarting
        MySQL Shell, use the
        <code class="literal">dba.getCluster([<em class="replaceable"><code>name</code></em>],[<em class="replaceable"><code>options</code></em>])</code>
        function. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>var cluster1 = dba.getCluster()</code></strong>
</pre><p>
        If you do not specify a cluster <em class="replaceable"><code>name</code></em>
        then the default cluster is returned.

        

        By default MySQL Shell attempts to connect to the primary
        instance of the cluster when you use
        <code class="literal">dba.getCluster()</code>. Set the
        <code class="literal">connectToPrimary</code> option to configure this
        behavior. If <code class="literal">connectToPrimary</code> is
        <code class="literal">true</code> and the active global MySQL Shell
        session is not to a primary instance, the cluster is queried for
        the primary member and the cluster object connects to it. If
        there is no quorum in the cluster, the operation fails. If
        <code class="literal">connectToPrimary</code> is <code class="literal">false</code>,
        the cluster object uses the active session, in other words the
        same instance as the MySQL Shell's current global session. If
        <code class="literal">connectToPrimary</code> is not specified,
        MySQL Shell treats <code class="literal">connectToPrimary</code> as
        <code class="literal">true</code>, and falls back to
        <code class="literal">connectToPrimary</code> being
        <code class="literal">false</code>.
      </p><p>
        To force connecting to a secondary when getting a cluster,
        establish a connection to the secondary member of the cluster
        and use the <code class="literal">connectToPrimary</code> option by
        issuing:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>shell.connect(secondary_member)</code></strong>
mysql-js&gt; <strong class="userinput"><code>var cluster1 = dba.getCluster(testCluster, {connectToPrimary:false})</code></strong>
</pre>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          Remember that secondary instances have
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a>, so you
          cannot write changes to them.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="connect-primary-innodb-cluster"></a>Finding the Primary</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250816304"></a><a class="indexterm" name="idm46444250814816"></a><p>
        When you are working with a single-primary InnoDB cluster or
        an InnoDB ReplicaSet, you need to connect to the primary
        instance for administration tasks so that configuration changes
        can be written to the metadata. To find the current primary you
        can:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            use the <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysqlsh.html#option_mysqlsh_redirect-primary" target="_top"><code class="option">--redirect-primary</code></a>
            option at MySQL Shell start up to ensure that the target
            server is part of an InnoDB cluster or
            InnoDB ReplicaSet. If the target instance is not the
            primary, MySQL Shell finds the primary and connects to it.
          </p></li><li class="listitem"><p>
            use the
            <code class="literal">shell.connectToPrimary([<em class="replaceable"><code>instance</code></em>,
            <em class="replaceable"><code>password</code></em>])</code> operation
            (added in version 8.0.20), which checks whether the target
            instance belongs to a cluster or replica set. If so,
            MySQL Shell opens a new session to the primary, sets the
            active global MySQL Shell session to the established
            session and returns it.
          </p><p>
            If an <em class="replaceable"><code>instance</code></em> is not provided,
            the operation attempts to use the active global MySQL Shell
            session. If an <em class="replaceable"><code>instance</code></em> is not
            provided and there is no active global MySQL Shell session,
            an exception is thrown. If the target instance does not
            belong to a cluster or replica set the operation fails with
            an error.
          </p></li><li class="listitem"><p>
            use the status operation, find the primary in the result,
            and manually connect to that instance.
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="describe-structure-innodb-cluster"></a>Using <code class="literal">cluster.describe()</code></h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250803216"></a><a class="indexterm" name="idm46444250801728"></a><p>
        To get information about the structure of the InnoDB cluster
        itself, use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.describe()</code>
        function:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.describe();</code></strong>
{
    "clusterName": "testCluster",
    "defaultReplicaSet": {
        "name": "default",
        "topology": [
            {
                "address": "ic-1:3306",
                "label": "ic-1:3306",
                "role": "HA"
            },
            {
                "address": "ic-2:3306",
                "label": "ic-2:3306",
                "role": "HA"
            },
            {
                "address": "ic-3:3306",
                "label": "ic-3:3306",
                "role": "HA"
            }
        ]
    }
}
</pre><p>
        The output from this function shows the structure of the
        InnoDB cluster including all of its configuration information,
        and so on. The address, label and role values match those
        described at <a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking a cluster's Status with Cluster.status()">Checking a cluster's Status with
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code></a> .
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="check-innodb-cluster-status"></a>Checking a cluster's Status with
<code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code></h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444250793008"></a><a class="indexterm" name="idm46444250790832"></a><p>
        Cluster objects provide the <code class="literal">status()</code> method
        that enables you to check how a cluster is running. Before you
        can check the status of the InnoDB cluster, you need to get a
        reference to the InnoDB cluster object by connecting to any of
        its instances. However, if you want to make changes to the
        configuration of the cluster, you must connect to a "R/W"
        instance. Issuing <code class="literal">status()</code> retrieves the
        status of the cluster based on the view of the cluster which the
        server instance you are connected to is aware of and outputs a
        status report.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          The instance's state in the cluster directly influences the
          information provided in the status report. Therefore ensure
          the instance you are connected to has a status of
          <code class="literal">ONLINE</code>.
</p>
</div>
<p>
        For information about how the InnoDB cluster is running, use
        the cluster's <code class="literal">status()</code> method:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>var cluster = dba.getCluster()</code></strong>
mysql-js&gt; <strong class="userinput"><code>cluster.status()</code></strong>
{
    "clusterName": "testcluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "primary": "ic-1:3306", 
        "ssl": "REQUIRED", 
        "status": "OK", 
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.", 
        "topology": {
            "ic-1:3306": {
                "address": "ic-1:3306", 
                "mode": "R/W", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }, 
            "ic-2:3306": {
                "address": "ic-2:3306", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }, 
            "ic-3:3306": {
                "address": "ic-3:3306", 
                "mode": "R/O", 
                "readReplicas": {}, 
                "role": "HA", 
                "status": "ONLINE"
            }
        }
    }, 
    "groupInformationSourceMember": "mysql://icadmin@ic-1:3306"
}
</pre><p>
        The output of
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>
        provides the following information:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">clusterName</code>: name assigned to this
            cluster during <code class="literal">dba.createCluster()</code>.
          </p></li><li class="listitem"><p>
            <code class="literal">defaultReplicaSet</code>: the server instances
            which belong to an InnoDB cluster and contain the data
            set.
          </p></li><li class="listitem"><p>
            <code class="literal">primary</code>: displayed when the cluster is
            operating in single-primary mode only. Shows the address of
            the current primary instance. If this field is not
            displayed, the cluster is operating in multi-primary mode.
          </p></li><li class="listitem"><p>
            <code class="literal">ssl</code>: whether secure connections are used
            by the cluster or not. Shows values of
            <code class="literal">REQUIRED</code> or <code class="literal">DISABLED</code>,
            depending on how the <code class="literal">memberSslMode</code> option
            was configured during either
            <code class="literal">createCluster()</code> or
            <code class="literal">addInstance()</code>. The value returned by this
            parameter corresponds to the value of the
            <a class="link" href="group-replication.html#sysvar_group_replication_ssl_mode"><code class="literal">group_replication_ssl_mode</code></a>
            server variable on the instance. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-securing" title="Securing your Cluster">Securing your Cluster</a>.
          </p></li><li class="listitem"><p>
            <code class="literal">status</code>: The status of this element of the
            cluster. For the overall cluster this describes the high
            availability provided by this cluster. The status is one of
            the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">ONLINE</code>: The instance is online and
                participating in the cluster.
              </p></li><li class="listitem"><p>
                <code class="literal">OFFLINE</code>: The instance has lost
                connection to the other instances.
              </p></li><li class="listitem"><p>
                <code class="literal">RECOVERING</code>: The instance is
                attempting to synchronize with the cluster by retrieving
                transactions it needs before it can become an
                <code class="literal">ONLINE</code> member.
              </p></li><li class="listitem"><p>
                <code class="literal">UNREACHABLE</code>: The instance has lost
                communication with the cluster.
              </p></li><li class="listitem"><p>
                <code class="literal">ERROR</code>: The instance has encountered
                an error during the recovery phase or while applying a
                transaction.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
                  Once an instance enters <code class="literal">ERROR</code>
                  state, the
                  <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a>
                  option is set to <code class="literal">ON</code>. To leave the
                  <code class="literal">ERROR</code> state you must manually
                  configure the instance with
                  <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>.
</p>
</div>
</li><li class="listitem"><p>
                <code class="literal">(MISSING)</code>: The state of an instance
                which is part of the configured cluster, but is
                currently unavailable.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
                  The <code class="literal">MISSING</code> state is specific to
                  InnoDB cluster, it is not a state generated by Group
                  Replication. MySQL Shell uses this state to indicate
                  instances that are registered in the metadata, but
                  cannot be found in the live cluster view.
</p>
</div>
</li></ul>
</div>
</li><li class="listitem"><p>
            <code class="literal">topology</code>: The instances which have been
            added to the cluster.
          </p></li><li class="listitem"><p>
            <code class="literal">Host name of instance</code>: The host name of
            an instance, for example localhost:3310.
          </p></li><li class="listitem"><p>
            <code class="literal">role</code>: what function this instance
            provides in the cluster. Currently only HA, for high
            availability.
          </p></li><li class="listitem"><p>
            <code class="literal">mode</code>: whether the server is read-write
            ("R/W") or read-only ("R/O"). From version 8.0.17, this is
            derived from the current state of the
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> variable on
            the instance, and whether the cluster has quorum. In
            previous versions the value of mode was derived from whether
            the instance was serving as a primary or secondary instance.
            Usually if the instance is a primary, then the mode is
            "R/W", and if the instance is a secondary the mode is "R/O".
            Any instances in a cluster that have no visible quorum are
            marked as "R/O", regardless of the state of the
            <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> variable.
          </p></li><li class="listitem"><p>
            <code class="literal">groupInformationSourceMember</code>: the
            internal connection used to get information about the
            cluster, shown as a URI-like connection string. Usually the
            connection initially used to create the cluster.
</p></li></ul>
</div>
<p>
        To display more information about the cluster use the
        <code class="literal">extended</code> option. From version 8.0.17, the
        <code class="literal">extended</code> option supports integer or Boolean
        values. To configure the additional information that
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status({'extended':<em class="replaceable"><code>value</code></em>})</code>
        provides, use the following values:

        
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            0: disables the additional information, the default
          </p></li><li class="listitem"><p>
            1: includes information about the Group Replication Protocol
            Version, Group name, cluster member UUIDs, cluster member
            roles and states as reported by Group Replication, and the
            list of fenced system variables
          </p></li><li class="listitem"><p>
            2: includes information about transactions processed by
            connection and applier
          </p></li><li class="listitem"><p>
            3: includes more detailed statistics about the replication
            performed by each cluster member.
</p></li></ul>
</div>
<p>
        Setting <code class="literal">extended</code> using Boolean values is the
        equivalent of setting the integer values 0 and 1. In versions
        prior to 8.0.17, the <code class="literal">extended</code> option was only
        Boolean. Similarly prior versions used the
        <code class="literal">queryMembers</code> Boolean option to provide more
        information about the instances in the cluster, which is the
        equivalent of setting <code class="literal">extended</code> to 3. The
        <code class="literal">queryMembers</code> option is deprecated and
        scheduled to be removed in a future release.
      </p><p>
        When you issue
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status({'extended':1})</code>,
        or the <code class="literal">extended</code> option is set to
        <code class="literal">true</code>, the output includes:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            the following additional attributes for the
            <code class="literal">defaultReplicaSet</code> object:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">GRProtocolVersion</code> is the Group
                Replication Protocol Version being used in the cluster.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
                  InnoDB cluster manages the Group Replication
                  Protocol version being used automatically, see
                  <a class="xref" href="mysql-innodb-cluster-userguide.html#innodb-cluster-group-replication-protocol" title="InnoDB cluster and Group Replication Protocol">InnoDB cluster and Group Replication Protocol</a>
                  for more information.
</p>
</div>
</li><li class="listitem"><p>
                <code class="literal">groupName</code> is the group's name, a
                UUID.
</p></li></ul>
</div>
</li><li class="listitem"><p>
            the following additional attributes for each object of the
            <code class="literal">topology</code> object:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">fenceSysVars</code> a list containing the
                name of the fenced system variables which are enabled.
                Currently the fenced system variables considered are
                <a class="link" href="server-administration.html#sysvar_read_only"><code class="literal">read_only</code></a>,
                <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> and
                <a class="link" href="server-administration.html#sysvar_offline_mode"><code class="literal">offline_mode</code></a>.
              </p></li><li class="listitem"><p>
                <code class="literal">memberId</code> Each cluster member UUID.
              </p></li><li class="listitem"><p>
                <code class="literal">memberRole</code> the Member Role as
                reported by the Group Replication plugin, see the
                <code class="literal">MEMBER_ROLE</code> column of the
                <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">replication_group_members</code></a>
                table.
              </p></li><li class="listitem"><p>
                <code class="literal">memberState</code> the Member State as
                reported by the Group Replication plugin, see the
                <code class="literal">MEMBER_STATE</code> column of the
                <a class="link" href="performance-schema.html#replication-group-members-table" title="26.12.11.9 The replication_group_members Table"><code class="literal">replication_group_members</code></a>
                table.
</p></li></ul>
</div>
</li></ul>
</div>
<p>
        To see information about recovery and regular transaction I/O,
        applier worker thread statistics and any lags; applier
        coordinator statistics, if parallel apply is enabled; error, and
        other information from I/O and applier threads issue use the
        values 2 and 3. A value of 3 is the equivalent of setting the
        deprecated <code class="literal">queryMembers</code> option to
        <code class="literal">true</code>. When you use these values, a connection
        to each instance in the cluster is opened so that additional
        instance specific statistics can be queried. The exact
        statistics that are included in the output depend on the state
        and configuration of the instance and the server version. This
        information matches that shown in the
        <a class="link" href="performance-schema.html#replication-group-member-stats-table" title="26.12.11.10 The replication_group_member_stats Table"><code class="literal">replication_group_member_stats</code></a>
        table, see the descriptions of the matching columns for more
        information. Instances which are <code class="literal">ONLINE</code> have
        a <code class="literal">transactions</code> section included in the
        output. Instances which are <code class="literal">RECOVERING</code> have a
        <code class="literal">recovery</code> section included in the output. When
        you set <code class="literal">extended</code> to 2, in either case, these
        sections can contain the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">appliedCount</code>: see
            <code class="literal">COUNT_TRANSACTIONS_REMOTE_APPLIED</code>
          </p></li><li class="listitem"><p>
            <code class="literal">checkedCount</code>: see
            <code class="literal">COUNT_TRANSACTIONS_CHECKED</code>
          </p></li><li class="listitem"><p>
            <code class="literal">committedAllMembers</code>: see
            <code class="literal">TRANSACTIONS_COMMITTED_ALL_MEMBERS</code>
          </p></li><li class="listitem"><p>
            <code class="literal">conflictsDetectedCount</code>: see
            <code class="literal">COUNT_CONFLICTS_DETECTED</code>
          </p></li><li class="listitem"><p>
            <code class="literal">inApplierQueueCount</code>: see
            <code class="literal">COUNT_TRANSACTIONS_REMOTE_IN_APPLIER_QUEUE</code>
          </p></li><li class="listitem"><p>
            <code class="literal">inQueueCount</code>: see
            <code class="literal">COUNT_TRANSACTIONS_IN_QUEUE</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastConflictFree</code>: see
            <code class="literal">LAST_CONFLICT_FREE_TRANSACTION</code>
          </p></li><li class="listitem"><p>
            <code class="literal">proposedCount</code>: see
            <code class="literal">COUNT_TRANSACTIONS_LOCAL_PROPOSED</code>
          </p></li><li class="listitem"><p>
            <code class="literal">rollbackCount</code>: see
            <code class="literal">COUNT_TRANSACTIONS_LOCAL_ROLLBACK</code>
</p></li></ul>
</div>
<p>
        When you set <code class="literal">extended</code> to 3, the
        <code class="literal">connection</code> section shows information from the
        <a class="link" href="performance-schema.html#replication-connection-status-table" title="26.12.11.2 The replication_connection_status Table"><code class="literal">replication_connection_status</code></a>
        table. The <code class="literal">connection</code> section can contain the
        following:
      </p><p>
        The <code class="literal">currentlyQueueing</code> section has information
        about the transactions currently queued:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">immediateCommitTimestamp</code>: see
            <code class="literal">QUEUEING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitToNowTime</code>: see
            <code class="literal">QUEUEING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitTimestamp</code>: see
            <code class="literal">QUEUEING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitToNowTime</code>: see
            <code class="literal">QUEUEING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">startTimestamp</code>: see
            <code class="literal">QUEUEING_TRANSACTION_START_QUEUE_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">transaction</code>: see
            <code class="literal">QUEUEING_TRANSACTION</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastHeartbeatTimestamp</code>: see
            <code class="literal">LAST_HEARTBEAT_TIMESTAMP</code>
</p></li></ul>
</div>
<p>
        The <code class="literal">lastQueued</code> section has information about
        the most recently queued transaction:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">endTimestamp</code>: see
            <code class="literal">LAST_QUEUED_TRANSACTION_END_QUEUE_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitTimestamp</code>: see
            <code class="literal">LAST_QUEUED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitToEndTime</code>:
            <code class="literal">LAST_QUEUED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitTimestamp</code>: see
            <code class="literal">LAST_QUEUED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitToEndTime</code>:
            <code class="literal">LAST_QUEUED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">queueTime</code>:
            <code class="literal">LAST_QUEUED_TRANSACTION_END_QUEUE_TIMESTAMP</code>
            minus
            <code class="literal">LAST_QUEUED_TRANSACTION_START_QUEUE_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">startTimestamp</code>: see
            <code class="literal">LAST_QUEUED_TRANSACTION_START_QUEUE_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">transaction</code>: see
            <code class="literal">LAST_QUEUED_TRANSACTION</code>
          </p></li><li class="listitem"><p>
            <code class="literal">receivedHeartbeats</code>: see
            <code class="literal">COUNT_RECEIVED_HEARTBEATS</code>
          </p></li><li class="listitem"><p>
            <code class="literal">receivedTransactionSet</code>: see
            <code class="literal">RECEIVED_TRANSACTION_SET</code>
          </p></li><li class="listitem"><p>
            <code class="literal">threadId</code>: see
            <code class="literal">THREAD_ID</code>
</p></li></ul>
</div>
<p>
        Instances which are using a multithreaded slave have a
        <code class="literal">workers</code> section which contains information
        about the worker threads, and matches the information shown by
        the
        <a class="link" href="performance-schema.html#replication-applier-status-by-worker-table" title="26.12.11.6 The replication_applier_status_by_worker Table"><code class="literal">replication_applier_status_by_worker</code></a>
        table.
      </p><p>
        The <code class="literal">lastApplied</code> section shows the following
        information about the last transaction applied by the worker:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">applyTime</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP</code>
            minus
            <code class="literal">LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">endTimestamp</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION_END_APPLY_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitTimestamp</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitToEndTime</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitTimestamp</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitToEndTime</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">startTimestamp</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION_START_APPLY_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">transaction</code>: see
            <code class="literal">LAST_APPLIED_TRANSACTION</code>
</p></li></ul>
</div>
<p>
        The <code class="literal">currentlyApplying</code> section shows the
        following information about the transaction currently being
        applied by the worker:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">immediateCommitTimestamp</code>: see
            <code class="literal">APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitToNowTime</code>: see
            <code class="literal">APPLYING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitTimestamp</code>: see
            <code class="literal">APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitToNowTime</code>: see
            <code class="literal">APPLYING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">startTimestamp</code>: see
            <code class="literal">APPLYING_TRANSACTION_START_APPLY_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">transaction</code>: see
            <code class="literal">APPLYING_TRANSACTION</code>
</p></li></ul>
</div>
<p>
        The <code class="literal">lastProcessed</code> section has the following
        information about the last transaction processed by the worker:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">bufferTime</code>:
            <code class="literal">LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP</code>
            minus
            <code class="literal">LAST_PROCESSED_TRANSACTION_START_BUFFER_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">endTimestamp</code>: see
            <code class="literal">LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitTimestamp</code>: see
            <code class="literal">LAST_PROCESSED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitToEndTime</code>:
            <code class="literal">LAST_PROCESSED_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
            minus
            <code class="literal">LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitTimestamp</code>: see
            <code class="literal">LAST_PROCESSED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitToEndTime</code>:
            <code class="literal">LAST_PROCESSED_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
            minus
            <code class="literal">LAST_PROCESSED_TRANSACTION_END_BUFFER_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">startTimestamp</code>: see
            <code class="literal">LAST_PROCESSED_TRANSACTION_START_BUFFER_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">transaction</code>: see
            <code class="literal">LAST_PROCESSED_TRANSACTION</code>
</p></li></ul>
</div>
<p>
        If parallel applier workers are enabled, then the number of
        objects in the workers array in <code class="literal">transactions</code>
        or <code class="literal">recovery</code> matches the number of configured
        workers and an additional coordinator object is included. The
        information shown matches the information in the
        <a class="link" href="performance-schema.html#replication-applier-status-by-coordinator-table" title="26.12.11.5 The replication_applier_status_by_coordinator Table"><code class="literal">replication_applier_status_by_coordinator</code></a>
        table. The object can contain:
      </p><p>
        The <code class="literal">currentlyProcessing</code> section has the
        following information about the transaction being processed by
        the worker:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">immediateCommitTimestamp</code>: see
            <code class="literal">PROCESSING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">immediateCommitToNowTime</code>:
            <code class="literal">PROCESSING_TRANSACTION_IMMEDIATE_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitTimestamp</code>: see
            <code class="literal">PROCESSING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">originalCommitToNowTime</code>:
            <code class="literal">PROCESSING_TRANSACTION_ORIGINAL_COMMIT_TIMESTAMP</code>
            minus <code class="literal">NOW()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">startTimestamp</code>: see
            <code class="literal">PROCESSING_TRANSACTION_START_BUFFER_TIMESTAMP</code>
          </p></li><li class="listitem"><p>
            <code class="literal">transaction</code>: see
            <code class="literal">PROCESSING_TRANSACTION</code>
</p></li></ul>
</div>
<p>
        <code class="literal">worker</code> objects have the following information
        if an error was detected in the
        <a class="link" href="performance-schema.html#replication-applier-status-by-worker-table" title="26.12.11.6 The replication_applier_status_by_worker Table"><code class="literal">replication_applier_status_by_worker</code></a>
        table:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">lastErrno</code>: see
            <code class="literal">LAST_ERROR_NUMBER</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastError</code>: see
            <code class="literal">LAST_ERROR_MESSAGE</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastErrorTimestamp</code>: see
            <code class="literal">LAST_ERROR_TIMESTAMP</code>
</p></li></ul>
</div>
<p>
        <code class="literal">connection</code> objects have the following
        information if an error was detected in the
        <a class="link" href="performance-schema.html#replication-connection-status-table" title="26.12.11.2 The replication_connection_status Table"><code class="literal">replication_connection_status</code></a>
        table:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">lastErrno</code>: see
            <code class="literal">LAST_ERROR_NUMBER</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastError</code>: see
            <code class="literal">LAST_ERROR_MESSAGE</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastErrorTimestamp</code>: see
            <code class="literal">LAST_ERROR_TIMESTAMP</code>
</p></li></ul>
</div>
<p>
        <code class="literal">coordinator</code> objects have the following
        information if an error was detected in the
        <a class="link" href="performance-schema.html#replication-applier-status-by-coordinator-table" title="26.12.11.5 The replication_applier_status_by_coordinator Table"><code class="literal">replication_applier_status_by_coordinator</code></a>
        table:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">lastErrno</code>: see
            <code class="literal">LAST_ERROR_NUMBER</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastError</code>: see
            <code class="literal">LAST_ERROR_MESSAGE</code>
          </p></li><li class="listitem"><p>
            <code class="literal">lastErrorTimestamp</code>: see
            <code class="literal">LAST_ERROR_TIMESTAMP</code>
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="innodb-cluster-monitoring-recovery"></a>Monitoring Recovery Operations</h3>

</div>

</div>

</div>
<p>
        The output of
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>
        shows information about the progress of recovery operations for
        instances in <code class="literal">RECOVERING</code> state. Information is
        shown for instances recovering using either MySQL Clone, or
        incremental recovery. Monitor these fields:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            The <code class="literal">recoveryStatusText</code> field includes
            information about the type of recovery being used. When
            MySQL Clone is working the field shows <span class="quote">“<span class="quote">Cloning in
            progress</span>”</span>. When incremental recovery is working the
            field shows <span class="quote">“<span class="quote">Distributed recovery in progress</span>”</span>.
          </p></li><li class="listitem"><p>
            When MySQL Clone is being used, the
            <code class="literal">recovery</code> field includes a dictionary with
            the following fields:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">cloneStartTime</code>: The timestamp of the
                start of the clone process
              </p></li><li class="listitem"><p>
                <code class="literal">cloneState</code>: The state of the clone
                progress
              </p></li><li class="listitem"><p>
                <code class="literal">currentStage</code>: The current stage which
                the clone process has reached
              </p></li><li class="listitem"><p>
                <code class="literal">currentStageProgress</code>: The current
                stage progress as a percentage of completion
              </p></li><li class="listitem"><p>
                <code class="literal">currentStageState</code>: The current stage
                state
</p></li></ul>
</div>
<p>
            Example
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>
            output, trimmed for brevity:
          </p><pre class="programlisting">                    ...
                    "recovery": {
                    "cloneStartTime": "2019-07-15 12:50:22.730", 
                    "cloneState": "In Progress", 
                    "currentStage": "FILE COPY", 
                    "currentStageProgress": 61.726837675213865, 
                    "currentStageState": "In Progress"
                    }, 
                    "recoveryStatusText": "Cloning in progress", 
                    ...
                </pre></li><li class="listitem"><p>
            When incremental recovery is being used, the
            <code class="literal">recovery</code> field includes a dictionary with
            the following field:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                <code class="literal">state</code>: The state of the
                <code class="literal">group_replication_recovery</code> channel
</p></li></ul>
</div>
<p>
            Example output
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>,
            trimmed for brevity:
          </p><pre class="programlisting">                    ...
                    "recovery": {
                    "state": "ON"
                    }, 
                    ...
</pre></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="innodb-cluster-group-replication-protocol"></a>InnoDB cluster and Group Replication Protocol</h3>

</div>

</div>

</div>
<p>
        From MySQL 8.0.16, Group Replication has the concept of a
        communication protocol for the group, see
        <a class="xref" href="group-replication.html#group-replication-communication-protocol" title="18.4.1.4 Setting a Group's Communication Protocol Version">Section 18.4.1.4, “Setting a Group's Communication Protocol Version”</a> for
        background information. The Group Replication communication
        protocol version usually has to be managed explicitly, and set
        to accommodate the oldest MySQL Server version that you want the
        group to support. However, InnoDB cluster automatically and
        transparently manages the communication protocol versions of its
        members, whenever the cluster topology is changed using
        AdminAPI operations. A cluster always uses the most recent
        communication protocol version that is supported by all the
        instances that are currently part of the cluster or joining it.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            When an instance is added to, removed from, or rejoins the
            cluster, or a rescan or reboot operation is carried out on
            the cluster, the communication protocol version is
            automatically set to a version supported by the instance
            that is now at the earliest MySQL Server version.
          </p></li><li class="listitem"><p>
            When you carry out a rolling upgrade by removing instances
            from the cluster, upgrading them, and adding them back into
            the cluster, the communication protocol version is
            automatically upgraded when the last remaining instance at
            the old MySQL Server version is removed from the cluster
            prior to its upgrade.
</p></li></ul>
</div>
<p>
        To see the communication protocol version being used in a
        cluster, use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>
        function with the <code class="literal">extended</code> option enabled.
        The communication protocol version is returned in the
        <code class="literal">GRProtocolVersion</code> field, provided that the
        cluster has quorum and no cluster members are unreachable.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="checking-version-on-instances"></a>Checking the MySQL Version on Instances</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250472864"></a><p>
        The following operations can report information about the MySQL
        Server version running on the instance:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>
          </p></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.describe()</code>
          </p></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan()</code>
</p></li></ul>
</div>
<p>
        The behavior varies depending on the MySQL Server version of the
        <em class="replaceable"><code>Cluster</code></em> object session.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code>
          </p><p>
            If either of the following requirements are met, a
            <code class="literal">version</code> string attribute is returned for
            each instance JSON object of the <code class="literal">topology</code>
            object:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                The <em class="replaceable"><code>Cluster</code></em> object's
                current session is version 8.0.11 or later.
              </p></li><li class="listitem"><p>
                The <em class="replaceable"><code>Cluster</code></em> object's
                current session is running a version earlier than
                version 8.0.11 but the <code class="literal">extended</code>
                option is set to 3 (or the deprecated
                <code class="literal">queryMembers</code> is
                <code class="literal">true</code>).
</p></li></ul>
</div>
<p>
            For example on an instance running version 8.0.16:
          </p><pre class="programlisting">"topology": {
    "ic-1:3306": {
        "address": "ic-1:3306",
        "mode": "R/W",
        "readReplicas": {},
        "role": "HA",
        "status": "ONLINE",
        "version": "8.0.16"
}</pre><p>
            For example on an instance running version 5.7.24:
          </p><pre class="programlisting">"topology": {
    "ic-1:3306": {
        "address": "ic-1:3306",
        "mode": "R/W",
        "readReplicas": {},
        "role": "HA",
        "status": "ONLINE",
        "version": "5.7.24"
}</pre></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.describe()</code>
          </p><p>
            If the <em class="replaceable"><code>Cluster</code></em> object's
            current session is version 8.0.11 or later, a
            <code class="literal">version</code> string attribute is returned for
            each instance JSON object of the <code class="literal">topology</code>
            object
          </p><p>
            For example on an instance running version 8.0.16:
          </p><pre class="programlisting">"topology": [
    {
        "address": "ic-1:3306",
        "label": "ic-1:3306",
        "role": "HA",
        "version": "8.0.16"
    }
]</pre></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan()</code>
          </p><p>
            If the <em class="replaceable"><code>Cluster</code></em> object's
            current session is version 8.0.11 or later, and the
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan()</code>
            operation detects instances which do not belong to the
            cluster, a <code class="literal">version</code> string attribute is
            returned for each instance JSON object of the
            <code class="literal">newlyDiscoveredInstance</code> object.
          </p><p>
            For example on an instance running version 8.0.16:
          </p><pre class="programlisting">"newlyDiscoveredInstances": [
    {
        "host": "ic-4:3306",
        "member_id": "82a67a06-2ba3-11e9-8cfc-3c6aa7197deb",
        "name": null,
        "version": "8.0.16"
    }
]	</pre></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="super-read-only-on-instance"></a>Super Read-only and Instances</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250438224"></a><p>
        Whenever Group Replication stops, the
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only</code></a> variable is set
        to <code class="literal">ON</code> to ensure no writes are made to the
        instance. When you try to use such an instance with the
        following AdminAPI commands you are given the choice to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a> on the
        instance:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">dba.configureInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">dba.configureLocalInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">dba.dropMetadataSchema()</code>
</p></li></ul>
</div>
<p>
        When AdminAPI encounters an instance which has
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a>, in
        interactive mode you are given the choice to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. For
        example:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>var myCluster = dba.dropMetadataSchema()</code></strong>
Are you sure you want to remove the Metadata? [y/N]: y
The MySQL instance at 'localhost:3310' currently has the super_read_only system
variable set to protect it from inadvertent updates from applications. You must
first unset it to be able to perform any changes to this instance.
For more information see:
https://dev.mysql.com/doc/refman/en/server-system-variables.html#sysvar_super_read_only.

Do you want to disable super_read_only and continue? [y/N]: y

Metadata Schema successfully removed. 
</pre><p>
        The number of current active sessions to the instance is shown.
        You must ensure that no applications can write to the instance
        inadvertently. By answering <code class="literal">y</code> you confirm
        that AdminAPI can write to the instance. If there is more than
        one open session to the instance listed, exercise caution before
        permitting AdminAPI to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>.
      </p><p>
        To force the function to set
        <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a> in a
        script, pass the <code class="literal">clearReadOnly</code> option set to
        <code class="literal">true</code>. For example
        <code class="literal">dba.configureInstance(<em class="replaceable"><code>instance</code></em>,
        {clearReadOnly: true}).</code>
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="configure-innodb-cluster-user"></a>Configuring Users for InnoDB Cluster</h3>

</div>

</div>

</div>
<p>
        The recommended way to create a user which can administer an
        InnoDB cluster is to use the <code class="literal">clusterAdmin</code>
        option with the <code class="literal">dba.configureInstance()</code> or
        <code class="literal">dba.configureLocalInstance()</code> operations. If
        you want to manually configure a user which can administer an
        InnoDB cluster that user requires the following privileges,
        all with <a class="link" href="security.html#priv_grant-option"><code class="literal">GRANT OPTION</code></a>:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Global privileges on *.* for
            <a class="link" href="security.html#priv_reload"><code class="literal">RELOAD</code></a>,
            <a class="link" href="security.html#priv_shutdown"><code class="literal">SHUTDOWN</code></a>,
            <a class="link" href="security.html#priv_process"><code class="literal">PROCESS</code></a>,
            <a class="link" href="security.html#priv_file"><code class="literal">FILE</code></a>,
            <a class="link" href="security.html#priv_select"><code class="literal">SELECT</code></a>,
            <a class="link" href="security.html#priv_super"><code class="literal">SUPER</code></a>,
            <a class="link" href="security.html#priv_replication-slave"><code class="literal">REPLICATION SLAVE</code></a>,
            <a class="link" href="security.html#priv_replication-client"><code class="literal">REPLICATION CLIENT</code></a>,
            <a class="link" href="security.html#priv_create-user"><code class="literal">CREATE USER</code></a>,
            <a class="link" href="security.html#priv_system-variables-admin"><code class="literal">SYSTEM_VARIABLES_ADMIN</code></a> and
            <a class="link" href="security.html#priv_persist-ro-variables-admin"><code class="literal">PERSIST_RO_VARIABLES_ADMIN</code></a>.
          </p></li><li class="listitem"><p>
            Schema specific privileges for
            <code class="literal">mysql_innodb_cluster_metadata.*</code> are
            <a class="link" href="security.html#priv_alter"><code class="literal">ALTER</code></a>,
            <a class="link" href="security.html#priv_alter-routine"><code class="literal">ALTER ROUTINE</code></a>,
            <a class="link" href="security.html#priv_create"><code class="literal">CREATE</code></a>,
            <a class="link" href="security.html#priv_create-routine"><code class="literal">CREATE ROUTINE</code></a>,
            <a class="link" href="security.html#priv_create-temporary-tables"><code class="literal">CREATE TEMPORARY TABLES</code></a>,
            <a class="link" href="security.html#priv_create-view"><code class="literal">CREATE VIEW</code></a>,
            <a class="link" href="security.html#priv_delete"><code class="literal">DELETE</code></a>,
            <a class="link" href="security.html#priv_drop"><code class="literal">DROP</code></a>,
            <a class="link" href="security.html#priv_event"><code class="literal">EVENT</code></a>,
            <a class="link" href="security.html#priv_execute"><code class="literal">EXECUTE</code></a>,
            <a class="link" href="security.html#priv_index"><code class="literal">INDEX</code></a>,
            <a class="link" href="security.html#priv_insert"><code class="literal">INSERT</code></a>,
            <a class="link" href="security.html#priv_lock-tables"><code class="literal">LOCK TABLES</code></a>,
            <a class="link" href="security.html#priv_references"><code class="literal">REFERENCES</code></a>,
            <a class="link" href="security.html#priv_show-view"><code class="literal">SHOW VIEW</code></a>,
            <a class="link" href="security.html#priv_trigger"><code class="literal">TRIGGER</code></a>,
            <a class="link" href="security.html#priv_update"><code class="literal">UPDATE</code></a>; and for
            <code class="literal">mysql.*</code> are
            <a class="link" href="security.html#priv_insert"><code class="literal">INSERT</code></a>,
            <a class="link" href="security.html#priv_update"><code class="literal">UPDATE</code></a>,
            <a class="link" href="security.html#priv_delete"><code class="literal">DELETE</code></a>.
</p></li></ul>
</div>
<p>
        If only read operations are needed, for example to create a user
        for monitoring purposes, an account with more restricted
        privileges can be used. To give the user
        <em class="replaceable"><code>your_user</code></em> the privileges needed to
        monitor InnoDB cluster issue:
      </p><pre data-lang="sql" class="programlisting">GRANT SELECT ON mysql_innodb_cluster_metadata.* TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.global_status TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_configuration TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_status TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_status_by_coordinator TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_applier_status_by_worker TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_connection_configuration TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_connection_status TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_group_member_stats TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.replication_group_members TO <em class="replaceable"><code>your_user@'%'</code></em>;
GRANT SELECT ON performance_schema.threads TO <em class="replaceable"><code>your_user@'%'</code></em> WITH GRANT OPTION; 
</pre><p>
        For more information, see
        <a class="xref" href="sql-statements.html#account-management-statements" title="13.7.1 Account Management Statements">Section 13.7.1, “Account Management Statements”</a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="configuring-automatic-rejoin-of-instances"></a>Configuring Automatic Rejoin of Instances</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250358896"></a><p>
        Instances running MySQL 8.0.16 and later support the Group
        Replication automatic rejoin functionality, which enables you to
        configure instances to automatically rejoin the cluster after
        being expelled. See
        <a class="xref" href="group-replication.html#group-replication-responses-failure" title="18.6.6 Responses to Failure Detection and Network Partitioning">Section 18.6.6, “Responses to Failure Detection and Network Partitioning”</a> for
        background information. AdminAPI provides the
        <code class="literal">autoRejoinTries</code> option to configure the
        number of tries instances make to rejoin the cluster after being
        expelled. By default instances do not automatically rejoin the
        cluster. You can configure the
        <code class="literal">autoRejoinTries</code> option at either the cluster
        level or for an individual instance using the following
        commands:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">dba.createCluster()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.addInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.setOption()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.setInstanceOption()</code>
</p></li></ul>
</div>
<p>
        The <code class="literal">autoRejoinTries</code> option accepts positive
        integer values between 0 and 2016 and the default value is 0,
        which means that instances do not try to automatically rejoin.
        When you are using the automatic rejoin functionality, your
        cluster is more tolerant to faults, especially temporary ones
        such as unreliable networks. But if quorum has been lost, you
        should not expect members to automatically rejoin the cluster,
        because majority is required to rejoin instances.
      </p><p>
        Instances running MySQL version 8.0.12 and later have the
        <a class="link" href="group-replication.html#sysvar_group_replication_exit_state_action"><code class="literal">group_replication_exit_state_action</code></a>
        variable, which you can configure using the AdminAPI
        <code class="literal">exitStateAction</code> option. This controls what
        instances do in the event of leaving the cluster unexpectedly.
        By default the <code class="literal">exitStateAction</code> option is
        <code class="literal">READ_ONLY,</code> which means that instances which
        leave the cluster unexpectedly become read-only. If
        <code class="literal">exitStateAction</code> is set to
        <code class="literal">OFFLINE_MODE</code> (available from MySQL 8.0.18),
        instances which leave the cluster unexpectedly become read-only
        and also enter offline mode, where they disconnect existing
        clients and do not accept new connections (except from clients
        with administrator privileges). If
        <code class="literal">exitStateAction</code> is set to
        <code class="literal">ABORT_SERVER</code> then in the event of leaving the
        cluster unexpectedly, the instance shuts down MySQL, and it has
        to be started again before it can rejoin the cluster. Note that
        when you are using the automatic rejoin functionality, the
        action configured by the <code class="literal">exitStateAction</code>
        option only happens in the event that all attempts to rejoin the
        cluster fail.
      </p><p>
        There is a chance you might connect to an instance and try to
        configure it using the AdminAPI, but at that moment the
        instance could be rejoining the cluster. This could happen
        whenever you use any of these operations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">Cluster.status()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">dba.getCluster()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.rejoinInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.addInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.removeInstance()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.rescan()</code>
          </p></li><li class="listitem"><p>
            <code class="literal">Cluster.checkInstanceState()</code>
</p></li></ul>
</div>
<p>
        These operations might provide extra information

        

        while the instance is automatically rejoining the cluster. In
        addition, when you are using
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.removeInstance()</code>,
        if the target instance is automatically rejoining the cluster
        the operation aborts unless you pass in
        <code class="literal">force:true</code>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="manage-sandbox-instances"></a>Managing Sandbox Instances</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250321824"></a><a class="indexterm" name="idm46444250320320"></a><a class="indexterm" name="idm46444250318816"></a><a class="indexterm" name="idm46444250317312"></a><a class="indexterm" name="idm46444250315808"></a><p>
        Once a sandbox instance is running, it is possible to change its
        status at any time using the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            To stop a sandbox instance use
            <code class="literal">dba.stopSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
            This stops the instance gracefully, unlike
            <code class="literal">dba.killSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
          </p></li><li class="listitem"><p>
            To start a sandbox instance use
            <code class="literal">dba.startSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
          </p></li><li class="listitem"><p>
            To kill a sandbox instance use
            <code class="literal">dba.killSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
            This stops the instance without gracefully stopping it and
            is useful in simulating unexpected halts.
          </p></li><li class="listitem"><p>
            To delete a sandbox instance use
            <code class="literal">dba.deleteSandboxInstance(<em class="replaceable"><code>instance</code></em>)</code>.
            This completely removes the sandbox instance from your file
            system.
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="innodb-cluster-binary-log-purging"></a>InnoDB Cluster and Binary Log Purging</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250302688"></a><p>
        In MySQL 8, the binary log is automatically purged (as defined
        by <a class="link" href="replication.html#sysvar_binlog_expire_logs_seconds"><code class="literal">binlog_expire_logs_seconds</code></a>).
        This means that a cluster which has been running for a longer
        time than
        <a class="link" href="replication.html#sysvar_binlog_expire_logs_seconds"><code class="literal">binlog_expire_logs_seconds</code></a>
        could eventually not contain an instance with a complete binary
        log that contains all of the transactions applied by the
        instances. This could result in instances needing to be
        provisioned automatically, for example using MySQL Enterprise Backup, before they
        could join the cluster. Instances running 8.0.17 and later
        support the MySQL Clone plugin, which resolves this issue by
        providing an automatic provisioning solution which does not rely
        on incremental recovery, see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-clone-deployment" title="21.2.5 Using MySQL Clone with InnoDB cluster">Section 21.2.5, “Using MySQL Clone with InnoDB cluster”</a>.
        Instances running a version earlier than 8.0.17 only support
        incremental recovery, and the result is that, depending on which
        version of MySQL the instance is running, instances might have
        to be provisioned automatically. Otherwise operations which rely
        on distributed recovery, such as
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
        and so on might fail.
      </p><p>
        On instances running earlier versions of MySQL the following
        rules are used for binary log purging:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Instances running a version earlier than 8.0.1 have no
            automatic binary log purging because the default value of
            <a class="link" href="replication.html#sysvar_expire_logs_days"><code class="literal">expire_logs_days</code></a> is 0.
          </p></li><li class="listitem"><p>
            Instances running a version later than 8.0.1 but earlier
            than 8.0.4 purge the binary log after 30 days because the
            default value of
            <a class="link" href="replication.html#sysvar_expire_logs_days"><code class="literal">expire_logs_days</code></a> is 30.
          </p></li><li class="listitem"><p>
            Instances running a version later than 8.0.10 purge the
            binary log after 30 days because the default value of
            <a class="link" href="replication.html#sysvar_binlog_expire_logs_seconds"><code class="literal">binlog_expire_logs_seconds</code></a>
            is 2592000 and the default value of
            <a class="link" href="replication.html#sysvar_expire_logs_days"><code class="literal">expire_logs_days</code></a> is 0.
</p></li></ul>
</div>
<p>
        Thus, depending on how long the cluster has been running binary
        logs could have been purged and you might have to provision
        instances manually. Similarly, if you manually purged binary
        logs you could encounter the same situation. Therefore you are
        strongly advised to upgrade to a version of MySQL later than
        8.0.17 to take full advantage of the automatic provisioning
        provided by MySQL Clone for distributed recovery, and to
        minimize downtime while provisioning instances for your
        InnoDB cluster.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="remove-instances-from-innodb-cluster"></a>Removing Instances from the InnoDB Cluster</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250284432"></a><a class="indexterm" name="idm46444250282976"></a><p>
        You can remove an instance from a cluster at any time should you
        wish to do so. This can be done with the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.removeInstance(<em class="replaceable"><code>instance</code></em>)</code>
        method, as in the following example:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.removeInstance('root@localhost:3310')</code></strong>

The instance will be removed from the InnoDB cluster. Depending on the instance
being the Seed or not, the Metadata session might become invalid. If so, please
start a new session to the Metadata Storage R/W instance.

Attempting to leave from the Group Replication group...

The instance 'localhost:3310' was successfully removed from the cluster.
</pre><p>
        You can optionally pass in the <code class="literal">interactive</code>
        option to control whether you are prompted to confirm the
        removal of the instance from the cluster. In interactive mode,
        you are prompted to continue with the removal of the instance
        (or not) in case it is not reachable. The
        <code class="literal"><em class="replaceable"><code>cluster</code></em>.removeInstance()</code>
        operation ensures that the instance is removed from the metadata
        of all the cluster members which are <code class="literal">ONLINE</code>,
        and the instance itself.
      </p><p>
        When the instance being removed has transactions which still
        need to be applied, AdminAPI waits for up to the number of
        seconds configured by the MySQL Shell
        <code class="literal">dba.gtidWaitTimeout</code> option for transactions
        (GTIDs) to be applied. The MySQL Shell
        <code class="literal">dba.gtidWaitTimeout</code> option has a default
        value of 60 seconds, see
        <a class="ulink" href="https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-configuring-options.html" target="_top">Configuring MySQL Shell Options</a> for
        information on changing the default. If the timeout value
        defined by <code class="literal">dba.gtidWaitTimeout</code> is reached
        when waiting for transactions to be applied and the
        <code class="literal">force</code> option is <code class="literal">false</code> (or
        not defined) then an error is issued and the remove operation is
        aborted. If the timeout value defined by
        <code class="literal">dba.gtidWaitTimeout</code> is reached when waiting
        for transactions to be applied and the <code class="literal">force</code>
        option is set to <code class="literal">true</code> then the operation
        continues without an error and removes the instance from the
        cluster.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          The <code class="literal">force</code> option should only be used with
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.removeInstance(<em class="replaceable"><code>instance</code></em>)</code>
          when you want to ignore any errors, for example unprocessed
          transactions or an instance being
          <code class="literal">UNREACHABLE</code>, and do not plan to reuse the
          instance with the cluster. Ignoring errors when removing an
          instance from the cluster could result in an instance which is
          not in synchrony with the cluster, preventing it from
          rejoining the cluster at a later time. Only use the
          <code class="literal">force</code> option when you plan to no longer use
          the instance with the cluster, in all other cases you should
          always try to recover the instance and only remove it when it
          is available and healthy, in other words with the status
          <code class="literal">ONLINE</code>.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="customize-your-cluster"></a>Customizing InnoDB clusters</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250259488"></a><a class="indexterm" name="idm46444250258032"></a><a class="indexterm" name="idm46444250256544"></a><a class="indexterm" name="idm46444250255040"></a><a class="indexterm" name="idm46444250253552"></a><p>
        When you create a cluster and add instances to it, values such
        as the group name, the local address, and the seed instances are
        configured automatically by AdminAPI. These default values are
        recommended for most deployments, but advanced users can
        override the defaults by passing the following options to the
        <code class="literal">dba.createCluster()</code> and
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>.
      </p><p>
        To customize the name of the replication group created by
        InnoDB cluster, pass the <code class="literal">groupName</code> option
        to the <code class="literal">dba.createCluster()</code> command. This sets
        the
        <a class="link" href="group-replication.html#sysvar_group_replication_group_name"><code class="literal">group_replication_group_name</code></a>
        system variable. The name must be a valid UUID.
      </p><p>
        To customize the address which an instance provides for
        connections from other instances, pass the
        <code class="literal">localAddress</code> option to the
        <code class="literal">dba.createCluster()</code> and
        <code class="literal">cluster.addInstance()</code> commands. Specify the
        address in the format
        <code class="literal"><em class="replaceable"><code>host</code></em>:<em class="replaceable"><code>port</code></em></code>.
        This sets the
        <a class="link" href="group-replication.html#sysvar_group_replication_local_address"><code class="literal">group_replication_local_address</code></a>
        system variable on the instance. The address must be accessible
        to all instances in the cluster, and must be reserved for
        internal cluster communication only. In other words do not use
        this address for communication with the instance.
      </p><p>
        To customize the instances used as seeds when an instance joins
        the cluster, pass the <code class="literal">groupSeeds</code> option to
        the <code class="literal">dba.createCluster()</code> and
        <code class="literal">cluster.addInstance()</code> commands. Seed
        instances are contacted when a new instance joins a cluster and
        used to provide data to the new instance. The addresses are
        specified as a comma separated list such as
        <code class="literal">host1:port1</code>,<code class="literal">host2:port2</code>.
        This configures the
        <a class="link" href="group-replication.html#sysvar_group_replication_group_seeds"><code class="literal">group_replication_group_seeds</code></a>
        system variable.
      </p><p>
        For more information see the documentation of the system
        variables configured by these AdminAPI options.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="rejoin-cluster"></a>Rejoining a Cluster</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250233456"></a><a class="indexterm" name="idm46444250231968"></a><p>
        If an instance leaves the cluster, for example because it lost
        connection, and for some reason it could not automatically
        rejoin the cluster, it might be necessary to rejoin it to the
        cluster at a later stage. To rejoin an instance to a cluster
        issue
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rejoinInstance(<em class="replaceable"><code>instance</code></em>)</code>.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          If the instance has
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=ON</code></a> then you
          might need to confirm that AdminAPI can set
          <a class="link" href="server-administration.html#sysvar_super_read_only"><code class="literal">super_read_only=OFF</code></a>. See
          <a class="xref" href="mysql-innodb-cluster-userguide.html#super-read-only-on-instance" title="Super Read-only and Instances">Super Read-only and Instances</a> for more
          information.
</p>
</div>
<p>
        In the case where an instance has not had it's
        configuration persisted (see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>),
        upon restart the instance does not rejoin the cluster
        automatically. The solution is to issue
        <code class="literal">cluster.rejoinInstance()</code> so that the instance
        is added to the cluster again and ensure the changes are
        persisted. Once the InnoDB cluster configuration is persisted
        to the instance's option file it rejoins the cluster
        automatically.
      </p><p>
        If you are rejoining an instance which has changed in some way
        then you might have to modify the instance to make the rejoin
        process work correctly. For example, when you restore a MySQL Enterprise Backup
        backup, the <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a>
        changes. Attempting to rejoin such an instance fails because
        InnoDB cluster instances are identified by the
        <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> variable. In such a
        situation, information about the instance's old
        <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a> must be removed
        from the InnoDB cluster metadata and then a
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan()</code>
        must be executed to add the instance to the metadata using it's
        new <a class="link" href="replication.html#sysvar_server_uuid"><code class="literal">server_uuid</code></a>. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">cluster.removeInstance("root@instanceWithOldUUID:3306", {force: true})

cluster.rescan()</pre><p>
        In this case you must pass the <code class="literal">force</code> option
        to the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.removeInstance()</code>
        method because the instance is unreachable from the cluster's
        perspective and we want to remove it from the InnoDB cluster
        metadata anyway.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="restore-cluster-from-quorum-loss"></a>Restoring a Cluster from Quorum Loss</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250210432"></a><a class="indexterm" name="idm46444250208928"></a><p>
        If an instance (or instances) fail, then a cluster can lose its
        quorum, which is the ability to vote in a new primary.

        

        This can happen when a there is a failure of enough instances
        that there is no longer a majority of the instances which make
        up the cluster to vote on Group Replication operations. When a
        cluster loses quorum you can no longer process write
        transactions with the cluster, or change the cluster's topology,
        for example by adding, rejoining, or removing instances. However
        if you have an instance online which contains the
        InnoDB cluster metadata, it is possible to restore a cluster
        with quorum. This assumes you can connect to an instance that
        contains the InnoDB cluster metadata, and that instance can
        contact the other instances you want to use to restore the
        cluster.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          This operation is potentially dangerous because it can create
          a split-brain scenario if incorrectly used and should be
          considered a last resort. Make absolutely sure that there are
          no partitions of this group that are still operating somewhere
          in the network, but not accessible from your location.
</p>
</div>
<p>
        Connect to an instance which contains the cluster's metadata,
        then use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.forceQuorumUsingPartitionOf(<em class="replaceable"><code>instance</code></em>)</code>
        operation, which restores the cluster based on the metadata on
        <em class="replaceable"><code>instance</code></em>, and then all the instances
        that are <code class="literal">ONLINE</code> from the point of view of the
        given instance definition are added to the restored cluster.
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.forceQuorumUsingPartitionOf("icadmin@ic-1:3306")</code></strong>

  Restoring replicaset 'default' from loss of quorum, by using the partition composed of [icadmin@ic-1:3306]

  Please provide the password for 'icadmin@ic-1:3306': ******
  Restoring the InnoDB cluster ...

  The InnoDB cluster was successfully restored using the partition from the instance 'icadmin@ic-1:3306'.

  WARNING: To avoid a split-brain scenario, ensure that all other members of the replicaset
  are removed or joined back to the group that was restored.
</pre><p>
        In the event that an instance is not automatically added to the
        cluster, for example if its settings were not persisted, use
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rejoinInstance()</code>
        to manually add the instance back to the cluster.
      </p><p>
        The restored cluster might not, and does not have to, consist of
        all of the original instances which made up the cluster. For
        example, if the original cluster consisted of the following five
        instances:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">ic-1</code>
          </p></li><li class="listitem"><p>
            <code class="literal">ic-2</code>
          </p></li><li class="listitem"><p>
            <code class="literal">ic-3</code>
          </p></li><li class="listitem"><p>
            <code class="literal">ic-4</code>
          </p></li><li class="listitem"><p>
            <code class="literal">ic-5</code>
</p></li></ul>
</div>
<p>
        and the cluster experiences a split-brain scenario, with
        <code class="literal">ic-1</code>, <code class="literal">ic-2</code>, and
        <code class="literal">ic-3</code> forming one partition while
        <code class="literal">ic-4</code> and <code class="literal">ic-5</code> form another
        partition. If you connect to <code class="literal">ic-1</code> and issue
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.forceQuorumUsingPartitionOf('icadmin@ic-1:3306')</code>
        to restore the cluster the reulting cluster would consist of
        these three instances:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">ic-1</code>
          </p></li><li class="listitem"><p>
            <code class="literal">ic-2</code>
          </p></li><li class="listitem"><p>
            <code class="literal">ic-3</code>
</p></li></ul>
</div>
<p>
        because <code class="literal">ic-1</code> sees <code class="literal">ic-2</code> and
        <code class="literal">ic-3</code> as <code class="literal">ONLINE</code> and does
        not see <code class="literal">ic-4</code> and <code class="literal">ic-5</code>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="reboot-outage"></a>Rebooting a Cluster from a Major Outage</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250172112"></a><a class="indexterm" name="idm46444250170640"></a><a class="indexterm" name="idm46444250169136"></a><p>
        

        If your cluster suffers from a complete outage, you can ensure
        it is reconfigured correctly using
        <code class="literal">dba.rebootClusterFromCompleteOutage()</code>. This
        operation takes the instance which MySQL Shell is currently
        connected to and uses its metadata to recover the cluster. In
        the event that a cluster's instances have completely stopped,
        the instances must be started and only then can the cluster be
        started. For example if the machine a sandbox cluster was
        running on has been restarted, and the instances were at ports
        3310, 3320 and 3330, issue:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>dba.startSandboxInstance(3310)</code></strong>
mysql-js&gt; <strong class="userinput"><code>dba.startSandboxInstance(3320)</code></strong>
mysql-js&gt; <strong class="userinput"><code>dba.startSandboxInstance(3330)</code></strong>
    </pre><p>
        This ensures the sandbox instances are running. In the case of a
        production deployment you would have to start the instances
        outside of MySQL Shell. Once the instances have started, you
        need to connect to an instance with the GTID superset, which
        means the instance which had applied the most transaction before
        the outage. If you are unsure which instance contains the GTID
        superset, connect to any instance and follow the interactive
        messages from the
        <code class="literal">dba.rebootClusterFromCompleteOutage()</code>, which
        detects if the instance you are connected to contains the GTID
        superset. Reboot the cluster by issuing:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>var cluster = dba.rebootClusterFromCompleteOutage();</code></strong>
</pre><p>
        The <code class="literal">dba.rebootClusterFromCompleteOutage()</code>
        operation then follows these steps to ensure the cluster is
        correctly reconfigured:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            The InnoDB cluster metadata found on the instance which
            MySQL Shell is currently connected to is checked to see if
            it contains the GTID superset, in other words the
            transactions applied by the cluster. If the currently
            connected instance does not contain the GTID superset, the
            operation aborts with that information. See the subsequent
            paragraphs for more information.
          </p></li><li class="listitem"><p>
            If the instance contains the GTID superset, the cluster is
            recovered based on the metadata of the instance.
          </p></li><li class="listitem"><p>
            Assuming you are running MySQL Shell in interactive mode, a
            wizard is run that checks which instances of the cluster are
            currently reachable and asks if you want to rejoin any
            discovered instances to the rebooted cluster.
          </p></li><li class="listitem"><p>
            Similarly, in interactive mode the wizard also detects
            instances which are currently not reachable and asks if you
            would like to remove such instances from the rebooted
            cluster.
</p></li></ul>
</div>
<p>
        If you are not using MySQL Shell's interactive mode, you
        can use the <code class="literal">rejoinInstances</code> and
        <code class="literal">removeInstances</code> options to manually configure
        instances which should be joined or removed during the reboot of
        the cluster.
      </p><p>
        If you encounter an error such as <span class="errortext">The active session
        instance isn't the most updated in comparison with the ONLINE
        instances of the Cluster's metadata.</span> then the
        instance you are connected to does not have the GTID superset of
        transactions applied by the cluster. In this situation, connect
        MySQL Shell to the instance suggested in the error message and
        issue <code class="literal">dba.rebootClusterFromCompleteOutage()</code>
        from that instance.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
          To manually detect which instance has the GTID superset rather
          than using the interactive wizard, check the
          <a class="link" href="replication.html#sysvar_gtid_executed"><code class="literal">gtid_executed</code></a> variable on
          each instance. For example issue:
        </p><pre data-lang="sql" class="programlisting">mysql-sql&gt; <strong class="userinput"><code>SHOW VARIABLES LIKE 'gtid_executed';</code></strong></pre><p>
          The instance which has applied the largest
          <a class="ulink" href="replication-gtids-concepts-gtid-sets" target="_top">GTID
          set</a> of transactions contains the GTID superset.
</p>
</div>
<p>
        If this process fails, and the cluster metadata has become badly
        corrupted, you might need to drop the metadata and create the
        cluster again from scratch. You can drop the cluster metadata
        using <code class="literal">dba.dropMetadataSchema()</code>.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          The <code class="literal">dba.dropMetadataSchema()</code> method should
          only be used as a last resort, when it is not possible to
          restore the cluster. It cannot be undone.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="rescan-cluster"></a>Rescanning a Cluster</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250138656"></a><a class="indexterm" name="idm46444250137168"></a><p>
        If you make configuration changes to a cluster outside of the
        AdminAPI commands, for example by changing an instance's
        configuration manually to resolve configuration issues or after
        the loss of an instance, you need to update the InnoDB cluster
        metadata so that it matches the current configuration of
        instances. In these cases, use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan()</code>
        operation, which enables you to update the InnoDB cluster
        metadata either manually or using an interactive wizard. The
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan()</code>
        operation can detect new active instances that are not
        registered in the metadata and add them, or obsolete instances
        (no longer active) still registered in the metadata, and remove
        them. You can automatically update the metadata depending on the
        instances found by the command, or you can specify a list of
        instance addresses to either add to the metadata or remove from
        the metadata. You can also update the topology mode stored in
        the metadata, for example after changing from single-primary
        mode to multi-primary mode outside of AdminAPI.
      </p><p>
        The syntax of the command is
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.rescan([options])</code>.
        The <code class="literal">options</code> dictionary supports the
        following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">interactive</code>: boolean value used to
            disable or enable the wizards in the command execution.
            Controls whether prompts and confirmations are provided. The
            default value is equal to MySQL Shell wizard mode,
            specified by <code class="literal">shell.options.useWizards</code>.
          </p></li><li class="listitem"><p>
            <code class="literal">addInstances</code>: list with the connection
            data of the new active instances to add to the metadata, or
            <span class="quote">“<span class="quote">auto</span>”</span> to automatically add missing instances
            to the metadata. The value <span class="quote">“<span class="quote">auto</span>”</span> is
            case-insensitive.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                Instances specified in the list are added to the
                metadata, without prompting for confirmation
              </p></li><li class="listitem"><p>
                In interactive mode, you are prompted to confirm the
                addition of newly discovered instances that are not
                included in the <code class="literal">addInstances</code> option
              </p></li><li class="listitem"><p>
                In non-interactive mode, newly discovered instances that
                are not included in the <code class="literal">addInstances</code>
                option are reported in the output, but you are not
                prompted to add them
</p></li></ul>
</div>
</li><li class="listitem"><p>
            <code class="literal">removeInstances</code>: list with the connection
            data of the obsolete instances to remove from the metadata,
            or <span class="quote">“<span class="quote">auto</span>”</span> to automatically remove obsolete
            instances from the metadata.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                Instances specified in the list are removed from the
                metadata, without prompting for confirmation
              </p></li><li class="listitem"><p>
                In interactive mode, you are prompted to confirm the
                removal of obsolete instances that are not included in
                the <code class="literal">removeInstances</code> option
              </p></li><li class="listitem"><p>
                In non-interactive mode, obsolete instances that are not
                included in the <code class="literal">removeInstances</code>
                option are reported in the output but you are not
                prompted to remove them
</p></li></ul>
</div>
</li><li class="listitem"><p>
            <code class="literal">updateTopologyMode</code>: boolean value used to
            indicate if the topology mode (single-primary or
            multi-primary) in the metadata should be updated (true) or
            not (false) to match the one being used by the cluster. By
            default, the metadata is not updated (false).
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                If the value is <code class="literal">true</code> then the
                InnoDB cluster metadata is compared to the current
                mode being used by Group Replication, and the metadata
                is updated if necessary. Use this option to update the
                metadata after making changes to the topology mode of
                your cluster outside of AdminAPI.
              </p></li><li class="listitem"><p>
                If the value is <code class="literal">false</code> then
                InnoDB cluster metadata about the cluster's topology
                mode is not updated even if it is different from the
                topology used by the cluster's Group Replication group
              </p></li><li class="listitem"><p>
                If the option is not specified and the topology mode in
                the metadata is different from the topology used by the
                cluster's Group Replication group, then:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: square; "><li class="listitem"><p>
                    In interactive mode, you are prompted to confirm the
                    update of the topology mode in the metadata
                  </p></li><li class="listitem"><p>
                    In non-interactive mode, if there is a difference
                    between the topology used by the cluster's Group
                    Replication group and the InnoDB cluster metadata,
                    it is reported and no changes are made to the
                    metadata
</p></li></ul>
</div>
</li><li class="listitem"><p>
                When the metadata topology mode is updated to match the
                Group Replication mode, the auto-increment settings on
                all instances are updated as described at
                <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-auto-increment" title="InnoDB cluster and Auto-increment">InnoDB cluster and Auto-increment</a>.
</p></li></ul>
</div>
</li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="check-instance-state"></a>Checking Instance State</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250100864"></a><a class="indexterm" name="idm46444250099408"></a><p>
        The <code class="literal">cluster.checkInstanceState()</code> function can
        be used to verify the existing data on an instance does not
        prevent it from joining a cluster. This process works by
        validating the instance's global transaction identifier (GTID)
        state compared to the GTIDs already processed by the cluster.
        For more information on GTIDs see
        <a class="xref" href="replication.html#replication-gtids-concepts" title="17.1.3.1 GTID Format and Storage">Section 17.1.3.1, “GTID Format and Storage”</a>. This check enables
        you to determine if an instance which has processed transactions
        can be added to the cluster.
      </p><p>
        The following demonstrates issuing this in a running
        MySQL Shell:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.checkInstanceState('icadmin@ic-4:3306')</code></strong>
</pre><p>
        

        The output of this function can be one of the following:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            OK new: the instance has not executed any GTID transactions,
            therefore it cannot conflict with the GTIDs executed by the
            cluster
          </p></li><li class="listitem"><p>
            OK recoverable: the instance has executed GTIDs which do not
            conflict with the executed GTIDs of the cluster seed
            instances
          </p></li><li class="listitem"><p>
            ERROR diverged: the instance has executed GTIDs which
            diverge with the executed GTIDs of the cluster seed
            instances
          </p></li><li class="listitem"><p>
            ERROR lost_transactions: the instance has more executed
            GTIDs than the executed GTIDs of the cluster seed instances
</p></li></ul>
</div>
<p>
        Instances with an OK status can be added to the cluster because
        any data on the instance is consistent with the cluster. In
        other words the instance being checked has not executed any
        transactions which conflict with the GTIDs executed by the
        cluster, and can be recovered to the same state as the rest of
        the cluster instances.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="dissolve-innodb-cluster"></a>Dissolving an InnoDB Cluster</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250086080"></a><a class="indexterm" name="idm46444250084624"></a><p>
        To dissolve an InnoDB cluster you connect to a read-write
        instance, for example the primary in a single-primary cluster,
        and use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.dissolve()</code>
        command. This removes all metadata and configuration associated
        with the cluster, and disables Group Replication on the
        instances. Any data that was replicated between the instances is
        not removed.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          There is no way to undo the dissolving of a cluster. To create
          it again use <code class="literal">dba.createCluster()</code>.
</p>
</div>
<p>
        The
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.dissolve()</code>
        operation can only configure instances which are
        <code class="literal">ONLINE</code> or reachable. If members of a cluster
        cannot be reached by the member where you issued the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.dissolve()</code>
        command you have to decide how the dissolve operation should
        proceed. If there is any chance you want to rejoin any instances
        that are identified as missing from the cluster, it is strongly
        recommended to cancel the dissolve operation and first bring the
        missing instances back online, before proceeding with a dissolve
        operation. This ensures that all instances can have their
        metadata updated correctly, and that there is no chance of a
        split-brain situation. However, if the instances from the
        cluster which cannot be reached have permanently left the
        cluster there could be no choice but to force the dissolve
        operation, which means that the missing instances are ignored
        and only online instances are affected by the operation.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          Forcing the dissolve operation to ignore cluster instances can
          result in instances which could not be reached during the
          dissolve operation continuing to operate, creating the risk of
          a split-brain situation. Only ever force a dissolve operation
          to ignore missing instances if you are sure there is no chance
          of the instance coming online again.
</p>
</div>
<p>
        In interactive mode, if members of a cluster are not reachable
        during a dissolve operation then an interactive prompt is
        displayed, for example:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code><em class="replaceable"><code>Cluster</code></em>.dissolve()</code></strong>
The cluster still has the following registered instances:
{
    "clusterName": "testCluster", 
    "defaultReplicaSet": {
        "name": "default", 
        "topology": [
            {
                "address": "ic-1:3306", 
                "label": "ic-1:3306", 
                "role": "HA"
            }, 
            {
                "address": "ic-2:3306", 
                "label": "ic-2:3306", 
                "role": "HA"
            }, 
            {
                "address": "ic-3:3306", 
                "label": "ic-3:3306", 
                "role": "HA"
            }
        ]
    }
}
WARNING: You are about to dissolve the whole cluster and lose the high
availability features provided by it. This operation cannot be reverted. All
members will be removed from the cluster and replication will be stopped,
internal recovery user accounts and the cluster metadata will be dropped. User
data will be maintained intact in all instances.

Are you sure you want to dissolve the cluster? [y/N]: y

ERROR: The instance 'ic-2:3306' cannot be removed because it is on a '(MISSING)'
state. Please bring the instance back ONLINE and try to dissolve the cluster
again. If the instance is permanently not reachable, then you can choose to
proceed with the operation and only remove the instance from the Cluster
Metadata.

Do you want to continue anyway (only the instance metadata will be removed)?
[y/N]: y

Instance 'ic-3:3306' is attempting to leave the cluster...  Instance 'ic-1:3306'
is attempting to leave the cluster...

WARNING: The cluster was successfully dissolved, but the following instance was
skipped: 'ic-2:3306'. Please make sure this instance is permanently unavailable
or take any necessary manual action to ensure the cluster is fully dissolved.
</pre><p>
        In this example, the cluster consisted of three instances, one
        of which was offline when dissolve was issued. The error is
        caught, and you are given the choice how to proceed. In this
        case the missing <code class="literal">ic-2</code> instance is ignored and
        the reachable members have their metadata updated.
      </p><p>
        When MySQL Shell is running in non-interactive mode, for
        example when running a batch file, you can configure the
        behavior of the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.dissolve()</code>
        operation using the <code class="literal">force</code> option. To force
        the dissolve operation to ignore any instances which are
        unreachable, issue:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code><em class="replaceable"><code>Cluster</code></em>.dissolve({force: true})</code></strong>
</pre><p>
        Any instances which can be reached are removed from the cluster,
        and any unreachable instances are ignored. The warnings in this
        section about forcing the removal of missing instances from a
        cluster apply equally to this technique of forcing the dissolve
        operation.
      </p><p>
        You can also use the <code class="literal">interactive</code> option with
        the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.dissolve()</code>
        operation to override the mode which MySQL Shell is running in,
        for example to make the interactive prompt appear when running a
        batch script. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code><em class="replaceable"><code>Cluster</code></em>.dissolve({interactive: true})</code></strong>
</pre><p>
        The <code class="literal">dba.gtidWaitTimeout</code> MySQL Shell option
        configures how long the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.dissolve()</code>
        operation waits for cluster transactions to be applied before
        removing a target instance from the cluster, but only if the
        target instance is <code class="literal">ONLINE</code>. An error is issued
        if the timeout is reached when waiting for cluster transactions
        to be applied on any of the instances being removed, except if
        force: true is used, which skips the error in that case.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          After issuing <code class="literal">cluster.dissolve()</code>, any
          variable assigned to the
          <code class="literal"><em class="replaceable"><code>Cluster</code></em></code> object
          is no longer valid.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="mysql-innodb-cluster-securing"></a>Securing your Cluster</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250052320"></a><a class="indexterm" name="idm46444250050832"></a><p>
        Server instances can be configured to use secure connections.
        For general information on using SSL with MySQL see
        <a class="xref" href="security.html#encrypted-connections" title="6.3 Using Encrypted Connections">Section 6.3, “Using Encrypted Connections”</a>. This section explains
        how to configure a cluster to use SSL. An additional security
        possibility is to configure which servers can access the
        cluster, see <a class="xref" href="mysql-innodb-cluster-userguide.html#create-whitelist-servers" title="Creating a Whitelist of Servers">Creating a Whitelist of Servers</a>.
</p>
<div class="important" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Important
</div>
<p>
          Once you have configured a cluster to use SSL you must add the
          servers to the <code class="literal">ipWhitelist</code>.
</p>
</div>
<p>
        When using <code class="literal">dba.createCluster()</code> to set up a
        cluster, if the server instance provides SSL encryption then it
        is automatically enabled on the seed instance. Pass the
        <code class="literal">memberSslMode</code> option to the
        <code class="literal">dba.createCluster()</code> method to specify a
        different SSL mode. The SSL mode of a cluster can only be set at
        the time of creation. The <code class="literal">memberSslMode</code>
        option is a string that configures the SSL mode to be used, it
        defaults to <code class="literal">AUTO</code>. The permitted values are
        <code class="literal">DISABLED</code>, <code class="literal">REQUIRED</code>, and
        <code class="literal">AUTO</code>. These modes are defined as:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            Setting
            <code class="literal">createCluster({memberSslMode:'DISABLED'})</code>
            ensures SSL encryption is disabled for the seed instance in
            the cluster.
          </p></li><li class="listitem"><p>
            Setting
            <code class="literal">createCluster({memberSslMode:'REQUIRED'})</code>
            then SSL encryption is enabled for the seed instance in the
            cluster. If it cannot be enabled an error is raised.
          </p></li><li class="listitem"><p>
            Setting
            <code class="literal">createCluster({memberSslMode:'AUTO'})</code>
            (the default) then SSL encryption is automatically enabled
            if the server instance supports it, or disabled if the
            server does not support it.
</p></li></ul>
</div>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">
<div class="admon-title">
Note
</div>
<p>
          When using the commercial version of MySQL, SSL is enabled by
          default and you might need to configure the whitelist for all
          instances. See <a class="xref" href="mysql-innodb-cluster-userguide.html#create-whitelist-servers" title="Creating a Whitelist of Servers">Creating a Whitelist of Servers</a>.
</p>
</div>
<p>
        When you issue the <code class="literal">cluster.addInstance()</code> and
        <code class="literal">cluster.rejoinInstance()</code> commands, SSL
        encryption on the instance is enabled or disabled based on the
        setting found for the seed instance.
      </p><p>
        When using <code class="literal">createCluster()</code> with the
        <code class="literal">adoptFromGR</code> option to adopt an existing Group
        Replication group, no SSL settings are changed on the adopted
        cluster:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">memberSslMode</code> cannot be used with
            <code class="literal">adoptFromGR</code>.
          </p></li><li class="listitem"><p>
            If the SSL settings of the adopted cluster are different
            from the ones supported by the MySQL Shell, in other words
            SSL for Group Replication recovery and Group Communication,
            both settings are not modified. This means you are not be
            able to add new instances to the cluster, unless you change
            the settings manually for the adopted cluster.
</p></li></ul>
</div>
<p>
        MySQL Shell always enables or disables SSL for the cluster for
        both Group Replication recovery and Group Communication, see
        <a class="xref" href="group-replication.html#group-replication-secure-socket-layer-support-ssl" title="18.5.2 Group Replication Secure Socket Layer (SSL) Support">Section 18.5.2, “Group Replication Secure Socket Layer (SSL) Support”</a>.
        A verification is performed and an error issued in case those
        settings are different for the seed instance (for example as the
        result of a <code class="literal">dba.createCluster()</code> using
        <code class="literal">adoptFromGR</code>) when adding a new instance to
        the cluster. SSL encryption must be enabled or disabled for all
        instances in the cluster. Verifications are performed to ensure
        that this invariant holds when adding a new instance to the
        cluster.

        
      </p><p>
        The <code class="literal">dba.deploySandboxInstance()</code> command
        attempts to deploy sandbox instances with SSL encryption support
        by default. If it is not possible, the server instance is
        deployed without SSL support. Use the
        <code class="literal">ignoreSslError</code> option set to false to ensure
        that sandbox instances are deployed with SSL support, issuing an
        error if SSL support cannot be provided. When
        <code class="literal">ignoreSslError</code> is true, which is the default,
        no error is issued during the operation if the SSL support
        cannot be provided and the server instance is deployed without
        SSL support.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="create-whitelist-servers"></a>Creating a Whitelist of Servers</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444250015968"></a><a class="indexterm" name="idm46444250014480"></a><p>
        

        When using a cluster's <code class="literal">createCluster()</code>,
        <code class="literal">addInstance()</code>, and
        <code class="literal">rejoinInstance()</code> methods you can optionally
        specify a list of approved servers that belong to the cluster,
        referred to as a whitelist. By specifying the whitelist
        explicitly in this way you can increase the security of your
        cluster because only servers in the whitelist can connect to the
        cluster.

        

        Using the <code class="literal">ipWhitelist</code> option configures the
        <a class="link" href="group-replication.html#sysvar_group_replication_ip_whitelist"><code class="literal">group_replication_ip_whitelist</code></a>
        system variable on the instance. By default, if not specified
        explicitly, the whitelist is automatically set to the private
        network addresses that the server has network interfaces on. To
        configure the whitelist, specify the servers to add with the
        <code class="literal">ipWhitelist</code> option when using the method. IP
        addresses must be specified in IPv4 format.

        

        Pass the servers as a comma separated list, surrounded by
        quotes. For example:
      </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; <strong class="userinput"><code>cluster.addInstance("icadmin@ic-3:3306", {ipWhitelist: "203.0.113.0/24, 198.51.100.110"})</code></strong>
</pre><p>
        This configures the instance to only accept connections from
        servers at addresses <code class="literal">203.0.113.0/24</code> and
        <code class="literal">198.51.100.110</code>. The whitelist can also
        include host names, which are resolved only when a connection
        request is made by another server.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
          Host names are inherently less secure than IP addresses in a
          whitelist. MySQL carries out FCrDNS verification, which
          provides a good level of protection, but can be compromised by
          certain types of attack. Specify host names in your whitelist
          only when strictly necessary, and ensure that all components
          used for name resolution, such as DNS servers, are maintained
          under your control. You can also implement name resolution
          locally using the hosts file, to avoid the use of external
          components.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="use-mysql-shell-execute-script"></a>Scripting AdminAPI</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249998160"></a><p>
        You can automate cluster configuration with scripts, which can
        be run using MySQL Shell. For example:
      </p><pre data-lang="terminal" class="programlisting">shell&gt; <strong class="userinput"><code>mysqlsh -f <em class="replaceable"><code>setup-innodb-cluster.js</code></em></code></strong>
</pre>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          Any command line options specified after the script file name
          are passed to the script and <span class="emphasis"><em>not</em></span> to
          MySQL Shell. You can access those options using the
          <code class="literal">os.argv</code> array in JavaScript, or the
          <code class="literal">sys.argv</code> array in Python. In both cases,
          the first option picked up in the array is the script name.
</p>
</div>
<p>
        The contents of an example script file is shown here:
      </p><pre data-lang="js" class="programlisting">print('InnoDB cluster sandbox set up\n');
print('==================================\n');
print('Setting up a MySQL InnoDB cluster with 3 MySQL Server sandbox instances.\n');
print('The instances will be installed in ~/mysql-sandboxes.\n');
print('They will run on ports 3310, 3320 and 3330.\n\n');

var dbPass = shell.prompt('Please enter a password for the MySQL root account: ', {type:"password"});

try {
   print('\nDeploying the sandbox instances.');
   dba.deploySandboxInstance(3310, {password: dbPass});
   print('.');
   dba.deploySandboxInstance(3320, {password: dbPass});
   print('.');
   dba.deploySandboxInstance(3330, {password: dbPass});
   print('.\nSandbox instances deployed successfully.\n\n');

   print('Setting up InnoDB cluster...\n');
   shell.connect('root@localhost:3310', dbPass);

   var cluster = dba.createCluster("prodCluster");

   print('Adding instances to the cluster.');
   cluster.addInstance({user: "root", host: "localhost", port: 3320, password: dbPass});
   print('.');
   cluster.addInstance({user: "root", host: "localhost", port: 3330, password: dbPass});
   print('.\nInstances successfully added to the cluster.');

   print('\nInnoDB cluster deployed successfully.\n');
} catch(e) {
   print('\nThe InnoDB cluster could not be created.\n\nError: ' +
   + e.message + '\n');
}</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="configuring-election-process"></a>Configuring the Election Process</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249985984"></a><a class="indexterm" name="idm46444249984496"></a><p>
        You can optionally configure how a single-primary cluster elects
        a new primary, for example to prefer one instance as the new
        primary to fail over to. Use the <code class="literal">memberWeight</code>
        option and pass it to the <code class="literal">dba.createCluster()</code>
        and <code class="literal">Cluster.addInstance()</code> methods when
        creating your cluster. The <code class="literal">memberWeight</code>
        option accepts an integer value between 0 and 100, which is a
        percentage weight for automatic primary election on failover.
        When an instance has a higher precentage number set by
        <code class="literal">memberWeight</code>, it is more likely to be elected
        as primary in a single-primary cluster. When a primary election
        takes place, if multiple instances have the same
        <code class="literal">memberWeight</code> value, the instances are then
        prioritized based on their server UUID in lexicographical order
        (the lowest) and by picking the first one.
      </p><p>
        Setting the value of <code class="literal">memberWeight</code> configures
        the
        <a class="link" href="group-replication.html#sysvar_group_replication_member_weight"><code class="literal">group_replication_member_weight</code></a>
        system variable on the instance. Group Replication limits the
        value range from 0 to 100, automatically adjusting it if a
        higher or lower value is provided. Group Replication uses a
        default value of 50 if no value is provided. See
        <a class="xref" href="group-replication.html#group-replication-single-primary-mode" title="18.1.3.1 Single-Primary Mode">Section 18.1.3.1, “Single-Primary Mode”</a> for more
        information.
      </p><p>
        For example to configure a cluster where <code class="literal">ic-3</code>
        is the preferred instance to fail over to in the event that
        <code class="literal">ic-1</code>, the current primary, leaves the cluster
        unexpectedly use <code class="literal">memberWeight</code> as follows:
      </p><pre data-lang="mysqlsh" class="programlisting">dba.createCluster('cluster1', {memberWeight:35})
var mycluster = dba.getCluster()
mycluster.addInstance('icadmin@ic2', {memberWeight:25})
mycluster.addInstance('icadmin@ic3', {memberWeight:50})</pre>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="mysql-innodb-cluster-failover-consistency"></a>Configuring Failover Consistency</h3>

</div>

</div>

</div>
<p>
        Group Replication provides the ability to specify the failover
        guarantees (eventual or <span class="quote">“<span class="quote">read your writes</span>”</span>) if a
        primary failover happens in single-primary mode (see
        <a class="xref" href="group-replication.html#group-replication-configuring-consistency-guarantees" title="18.4.2.2 Configuring Transaction Consistency Guarantees">Section 18.4.2.2, “Configuring Transaction Consistency Guarantees”</a>).
        You can configure the failover guarantees of an InnoDB cluster
        at creation by passing the <code class="literal">consistency</code> option
        (prior to version 8.0.16 this option was the
        <code class="literal">failoverConsistency</code> option, which is now
        deprecated) to the <code class="literal">dba.createCluster()</code>
        operation, which configures the
        <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
        system variable on the seed instance. This option defines the
        behavior of a new fencing mechanism used when a new primary is
        elected in a single-primary group. The fencing restricts
        connections from writing and reading from the new primary until
        it has applied any pending backlog of changes that came from the
        old primary (sometimes referred to as <span class="quote">“<span class="quote">read your
        writes</span>”</span>). While the fencing mechanism is in place,
        applications effectively do not see time going backward for a
        short period of time while any backlog is applied. This ensures
        that applications do not read stale information from the newly
        elected primary.
      </p><p>
        The <code class="literal">consistency</code> option is only supported if
        the target MySQL server version is 8.0.14 or later, and
        instances added to a cluster which has been configured with the
        <code class="literal">consistency</code> option are automatically
        configured to have
        <a class="link" href="group-replication.html#sysvar_group_replication_consistency"><code class="literal">group_replication_consistency</code></a>
        the same on all cluster members that have support for the
        option. The variable default value is controlled by Group
        Replication and is <code class="literal">EVENTUAL</code>, change the
        <code class="literal">consistency</code> option to
        <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code> to enable the
        fencing mechanism. Alternatively use
        <code class="literal">consistency=0</code> for <code class="literal">EVENTUAL</code>
        and <code class="literal">consistency=1</code> for
        <code class="literal">BEFORE_ON_PRIMARY_FAILOVER</code>.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          Using the <code class="literal">consistency</code> option on a
          multi-primary InnoDB cluster has no effect but is allowed
          because the cluster can later be changed into single-primary
          mode with the
          <code class="literal"><em class="replaceable"><code>Cluster</code></em>.switchToSinglePrimaryMode()</code>
          operation.
</p>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="mysql-innodb-cluster-change-topology"></a>Changing a Cluster's Topology</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249949728"></a><a class="indexterm" name="idm46444249948224"></a><a class="indexterm" name="idm46444249946720"></a><a class="indexterm" name="idm46444249945216"></a><p>
        By default, an InnoDB cluster runs in single-primary mode,
        where the cluster has one primary server that accepts read and
        write queries (R/W), and all of the remaining instances in the
        cluster accept only read queries (R/O). When you configure a
        cluster to run in multi-primary mode, all of the instances in
        the cluster are primaries, which means that they accept both
        read and write queries (R/W). If a cluster has all of its
        instances running MySQL server version 8.0.15 or later, you can
        make changes to the topology of the cluster while the cluster is
        online. In previous versions it was necessary to completely
        dissolve and re-create the cluster to make the configuration
        changes. This uses the group action coordinator exposed through
        the UDFs described at
        <a class="xref" href="group-replication.html#group-replication-configuring-online-group" title="18.4.1 Configuring an Online Group">Section 18.4.1, “Configuring an Online Group”</a>,
        and as such you should observe the rules for configuring online
        groups.
</p>
<div class="note" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Note
</div>
<p>
          multi-primary mode is considered an advanced mode
</p>
</div>
<p>
        Usually a single-primary cluster elects a new primary when the
        current primary leaves the cluster unexpectedly, for example due
        to an unexpected halt. The election process is normally used to
        choose which of the current secondaries becomes the new primary.
        To override the election process and force a specific server to
        become the new primary, use the
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.setPrimaryInstance(<em class="replaceable"><code>instance</code></em>)</code>
        function, where <em class="replaceable"><code>instance</code></em> specifies
        the connection to the instance which should become the new
        primary. This enables you to configure the underlying Group
        Replication group to choose a specific instance as the new
        primary, bypassing the election process.
      </p><p>
        You can change the mode (sometimes described as the topology)
        which a cluster is running in between single-primary and
        multi-primary using the following operations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.switchToMultiPrimaryMode()</code>,
            which switches the cluster to multi-primary mode. All
            instances become primaries.
          </p></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.switchToSinglePrimaryMode([<em class="replaceable"><code>instance</code></em>])</code>,
            which switches the cluster to single-primary mode. If
            <em class="replaceable"><code>instance</code></em> is specified, it becomes
            the primary and all the other instances become secondaries.
            If <em class="replaceable"><code>instance</code></em> is not specified, the
            new primary is the instance with the highest member weight
            (and the lowest UUID in case of a tie on member weight).
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="mysql-innodb-cluster-setting-options"></a>Setting Options for InnoDB cluster</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249929424"></a><a class="indexterm" name="idm46444249927648"></a><a class="indexterm" name="idm46444249926144"></a><p>
        You can check and modify the settings in place for an
        InnoDB cluster while the instances are online. To check the
        current settings of a cluster, use the following operation:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.options()</code>,
            which lists the configuration options for the cluster and
            its instances. A boolean option <code class="literal">all</code> can
            also be specified to include information about all Group
            Replication system variables in the output.
</p></li></ul>
</div>
<p>
        You can configure the options of an InnoDB cluster at a
        cluster level or instance level, while instances remain online.
        This avoids the need to remove, reconfigure and then again add
        the instance to change InnoDB cluster options. Use the
        following operations:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.setOption(<em class="replaceable"><code>option</code></em>,
            <em class="replaceable"><code>value</code></em>)</code> to change the
            settings of all cluster instances globally or cluster global
            settings such as <code class="literal">clusterName</code>.
          </p></li><li class="listitem"><p>
            <code class="literal"><em class="replaceable"><code>Cluster</code></em>.setInstanceOption(instance,
            <em class="replaceable"><code>option</code></em>,
            <em class="replaceable"><code>value</code></em>)</code> to change the
            settings of individual cluster instances
</p></li></ul>
</div>
<p>
        The way which you use InnoDB cluster options with the
        operations listed depends on whether the option can be changed
        to be the same on all instances or not. These options are
        changeable at both the cluster (all instances) and per instance
        level:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">exitStateAction</code>
          </p></li><li class="listitem"><p>
            <code class="literal">memberWeight</code>
</p></li></ul>
</div>
<p>
        This option is changeable at the per instance level only:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">label</code>
</p></li></ul>
</div>
<p>
        These options are changeable at the cluster level only:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            <code class="literal">consistency</code>
          </p></li><li class="listitem"><p>
            <code class="literal">expelTimeout</code>
          </p></li><li class="listitem"><p>
            <code class="literal">clusterName</code>
</p></li></ul>
</div>

</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h3 class="title"><a name="mysql-innodb-cluster-auto-increment"></a>InnoDB cluster and Auto-increment</h3>

</div>

</div>

</div>
<p>
        When you are using an instance as part of an InnoDB cluster,
        the <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a>
        and <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a>
        variables are configured to avoid the possibility of auto
        increment collisions for multi-primary clusters up to a size of
        9 (the maximum supported size of a Group Replication group). The
        logic used to configure these variables can be summarized as:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            If the group is running in single-primary mode, then set
            <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a> to
            1 and <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a>
            to 2.
          </p></li><li class="listitem"><p>
            If the group is running in multi-primary mode, then when the
            cluster has 7 instances or less set
            <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a> to
            7 and <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a>
            to 1 + <a class="link" href="replication.html#sysvar_server_id"><code class="literal">server_id</code></a> % 7. If a
            multi-primary cluster has 8 or more instances set
            <a class="link" href="replication.html#sysvar_auto_increment_increment"><code class="literal">auto_increment_increment</code></a> to
            the number of instances and
            <a class="link" href="replication.html#sysvar_auto_increment_offset"><code class="literal">auto_increment_offset</code></a> to 1
            + <a class="link" href="replication.html#sysvar_server_id"><code class="literal">server_id</code></a> % the number of
            instances.
</p></li></ul>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-replicasets"></a>21.6 InnoDB ReplicaSet</h2>

</div>

</div>

</div>
<div class="toc">
<dl class="toc"><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#mysql-innodb-replicasets-introduction">21.6.1 InnoDB ReplicaSet Introduction</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#deploying-innodb-replicasets">21.6.2 Deploying InnoDB ReplicaSet</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#adding-replicaset-instances">21.6.3 Adding Instances to a Replica Set</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#replicaset-adopting">21.6.4 Adopting an Existing Replication Set Up</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#working-with-replicasets">21.6.5 Working with InnoDB ReplicaSet</a></span></dt><dt><span class="section"><a href="mysql-innodb-cluster-userguide.html#replicasets-working-with-router">21.6.6 Using Replica Sets with MySQL Router</a></span></dt></dl>
</div>
<a class="indexterm" name="idm46444249883808"></a><p>
      This section documents InnoDB ReplicaSet, added in version
      8.0.19.
</p>
<div class="section">

<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="mysql-innodb-replicasets-introduction"></a>21.6.1 InnoDB ReplicaSet Introduction</h3>
</div>
</div>
</div>
<a class="indexterm" name="idm46444249881104"></a><p>
        The AdminAPI includes support for InnoDB ReplicaSet, that
        enables you to administer a set of MySQL instances running
        asynchronous GTID-based replication in a similar way to
        InnoDB cluster. An InnoDB ReplicaSet consists of a single
        primary and multiple secondaries (traditionally referred to as
        the MySQL replication master and slaves). You administer your
        replica sets using a <code class="literal">ReplicaSet</code> object and
        the AdminAPI operations, for example to check the status of
        the InnoDB ReplicaSet, and manually failover to a new primary
        in the event of a failure. Similar to InnoDB cluster, MySQL Router
        supports bootstrapping against InnoDB ReplicaSet, which means
        you can automatically configure MySQL Router to use your
        InnoDB ReplicaSet without having to manually configure files.
        This makes InnoDB ReplicaSet a quick and easy way to get MySQL
        replication and MySQL Router up and running, making it well suited
        to scaling out reads, and provides manual failover capabilities
        in use cases that do not require the high availability offered
        by InnoDB cluster.
      </p><p>
        In addition to deploying an InnoDB ReplicaSet using
        AdminAPI, you can adopt an existing replication setup.
        AdminAPI configures the InnoDB ReplicaSet based on the
        topology of the replication setup. Once the replication setup
        has been adopted, you administer it in the same way as an
        InnoDB ReplicaSet deployed from scratch. This enables you to
        take advantage of AdminAPI and MySQL Router without the need to
        create a new replica set. For more information see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#replicaset-adopting" title="21.6.4 Adopting an Existing Replication Set Up">Section 21.6.4, “Adopting an Existing Replication Set Up”</a>.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="replicaset-limitations"></a>InnoDB ReplicaSet Limitations</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444249874352"></a><p>
          

          An InnoDB ReplicaSet has several limitations compared to a
          InnoDB cluster and thus, it is recommended that you deploy
          InnoDB cluster wherever possible. Generally, a
          InnoDB ReplicaSet on its own does not provide high
          availability. Among the limitations of InnoDB ReplicaSet
          are:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              No automatic failover. In events where the primary becomes
              unavailable, a failover needs to be triggered manually
              using AdminAPI before any changes are possible again.
              However, secondary instances remain available for reads.
            </p></li><li class="listitem"><p>
              No protection from partial data loss due to an unexpected
              halt or unavailability. Transactions that have not yet
              been applied by the time of the halt could become lost.
            </p></li><li class="listitem"><p>
              No protection against inconsistencies after a crash or
              unavailability. If a failover promotes a secondary while
              the former primary is still available (for example due to
              a network partition), inconsistencies could be introduced
              because of the split-brain.
</p></li></ul>
</div>

</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="deploying-innodb-replicasets"></a>21.6.2 Deploying InnoDB ReplicaSet</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249866336"></a><p>
        You deploy InnoDB ReplicaSet in a similar way to
        InnoDB cluster. First you configure some MySQL server
        instances, the minimum is two instances. One functions as the
        primary, in this tutorial <code class="literal">rs-1</code>; the other
        instance functions as the secondary, in this tutorial
        <code class="literal">rs-2</code>; which replicates the transactions
        applied by the primary. This is the equivalent of the master and
        slave known from asynchronous MySQL replication. Then you
        connect to one of the instances using MySQL Shell, and create a
        replica set. Once the replica set has been created, you can add
        instances to it.
      </p><p>
        InnoDB ReplicaSet is compatible with sandbox instances, which
        you can use to deploy locally, for example for testing purposes.
        See <a class="xref" href="mysql-innodb-cluster-userguide.html#deploy-sandbox-instances" title="Deploying Sandbox Instances">Deploying Sandbox Instances</a> for instructions.
        However, this tutorial assumes you are deploying a production
        InnoDB ReplicaSet, where each instance is running on a
        different host.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="innodb-replicaset-prerequisites"></a>InnoDB ReplicaSet Prerequisites</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444249859824"></a><p>
          To use InnoDB ReplicaSet you should be aware of the
          following prerequisites:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              Only instances running MySQL version 8.0 and later are
              supported
            </p></li><li class="listitem"><p>
              GTID-based replication is only supported, binary log file
              position replication is not compatible with
              InnoDB ReplicaSet
            </p></li><li class="listitem"><p>
              Only Row Based Replication (RBR) is supported, Statement
              Based Replication (SBR) is unsupported
            </p></li><li class="listitem"><p>
              Replication filters are not supported
            </p></li><li class="listitem"><p>
              Unmanaged replication channels are not allowed in any
              instance
            </p></li><li class="listitem"><p>
              A replica set consists of maximum one primary instance,
              and one or multiple secondaries are supported. Although
              there is no limit to the number of secondaries you can add
              to a replica set, each MySQL Router connected to a replica set
              monitors each instance. Therefore, the more instances that
              are added to a replica set, the more monitoring has to be
              done.
            </p></li><li class="listitem"><p>
              The replica set must be entirely managed by MySQL Shell.
              For example, the replication account is created and
              managed by MySQL Shell. Making configuration changes to
              the instance outside of MySQL Shell, for example using
              SQL statements directly to change the primary, is not
              supported. Always use MySQL Shell to work with
              InnoDB ReplicaSet.
</p></li></ul>
</div>
<p>
          AdminAPI and InnoDB ReplicaSet enable you to work with
          MySQL replication without a deep understanding of the
          underlying concepts. However, for background information see
          <a class="xref" href="replication.html" title="Chapter 17 Replication">Chapter 17, <i>Replication</i></a>.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="configuring-replicaset-instances"></a>Configuring InnoDB Replica Set Instances</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249847824"></a><p>
          Use
          <code class="literal">dba.configureReplicaSetInstance(<em class="replaceable"><code>instance</code></em>)</code>
          to configure each instance you want to use in your replica
          set. MySQL Shell can either connect to an instance and then
          configure it, or you can pass in <code class="literal">instance</code>
          to configure a specific remote instance. How you proceed
          depends on whether the instance supports persisting settings,
          see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-persisting-settings" title="Persisting Settings">Persisting Settings</a>.
          For example, on an instance which does not support persisting
          settings, connect with a user with suitable privileges to
          configure the instance:
        </p><pre class="programlisting">mysql-js&gt; \connect root@example1.com:3306</pre><p>
          The <code class="literal">dba.configureReplicaSetInstance()</code>
          function can optionally create an administrator account, if
          the <code class="literal">clusterAdmin</code> option is provided. The
          account is created with the correct set of privileges required
          to manage InnoDB cluster and InnoDB ReplicaSet. The
          preferred method to create users to administer a replica set
          is using the <code class="literal">clusterAdmin</code> option.
</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Tip
</div>
<p>
            The administrator account must have the same user name and
            password across all instances of the same cluster or replica
            set.
</p>
</div>
<p>
          To configure the instance at <code class="literal">rs-1:3306</code>,
          with a cluster administrator named <code class="literal">rsadmin</code>
          issue:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; dba.configureReplicaSetInstance('root@rs-1:3306', \ 
{clusterAdmin: "'rsadmin'@'rs-1%'"});</pre><p>
          The interactive prompt requests the password required by the
          specified user. To configure the instance MySQL Shell is
          currently connected to, you can specify a null instance
          definition. For example issue:
        </p><pre data-lang="mysqlsh" class="programlisting">mysql-js&gt; dba.configureReplicaSetInstance('', {clusterAdmin: "'rsadmin'@'rs-1%'"});</pre><p>
          The interactive prompt requests the password required by the
          specified user. This checks the instance which MySQL Shell is
          currently connected to is valid for use in a
          InnoDB ReplicaSet. Settings which are not compatible with
          InnoDB ReplicaSet are configured if possible. The cluster
          administrator account is created with the privileges required
          for InnoDB ReplicaSet.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="creating-a-replicaset"></a>Creating an InnoDB Replica Set</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249830960"></a><p>
          Once you have configured your instances, connect to an
          instance and use <code class="literal">dba.createReplicaSet()</code> to
          create a managed replica set that uses MySQL asynchronous
          replication, as opposed to MySQL Group Replication used by
          InnoDB cluster. The MySQL instance which MySQL Shell is
          currently connected to is used as the initial primary of the
          replica set. Only TCP/IP connections are supported for this
          operation.
        </p><p>
          The <code class="literal">dba.createReplicaSet()</code> operation
          performs several checks to ensure that the instance state and
          configuration are compatible with a managed replica set and if
          so, a metadata schema is initialized on the instance. If you
          want to check the operation but not actually make any changes
          to the instances, use the <code class="literal">dryRun</code> option.
          This shows what actions the MySQL Shell would take to create
          the replica set. If the replica set is created successfully, a
          <code class="literal">ReplicaSet</code> object is returned. Therefore it
          is best practice to assign the returned
          <code class="literal">ReplicaSet</code> to a variable. This enables you
          to work with the replica set, for example by calling the
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.status()</code>
          operation. To create a replica set named
          <em class="replaceable"><code>example</code></em> on instance
          <code class="literal">rs-1</code> and assign it to the
          <code class="literal">rs</code> variable, issue:
        </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>\connect root@rs-1:3306</code></strong>
...
mysql-js&gt; <strong class="userinput"><code>var rs = dba.createReplicaSet("example")</code></strong>
A new replicaset with instance 'rs-1:3306' will be created.

* Checking MySQL instance at rs-1:3306

This instance reports its own address as rs-1:3306
rs-1:3306: Instance configuration is suitable.

* Updating metadata...

ReplicaSet object successfully created for rs-1:3306.
Use rs.add_instance() to add more asynchronously replicated instances to this replicaset
and rs.status() to check its status.
</pre><p>
          To verify that the operation was successful, you work with the
          returned <code class="literal">ReplicaSet</code> object. For example
          this provides the
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.status()</code>
          operation, which displays information about the replica set.
          We already assigned the returned <code class="literal">ReplicaSet</code>
          to the variable <code class="literal">rs</code>, so issue:
        </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>rs.status()</code></strong>
{
    "replicaSet": {
        "name": "example", 
        "primary": "rs-1:3306", 
        "status": "AVAILABLE", 
        "statusText": "All instances available.", 
        "topology": {
            "rs-1:3306": {
                "address": "rs-1:3306", 
                "instanceRole": "PRIMARY", 
                "mode": "R/W", 
                "status": "ONLINE"
            }
        }, 
        "type": "ASYNC"
    }
}
</pre><p>
          This output shows that the replica set named
          <code class="literal">example</code> has been created, and that the
          primary is <code class="literal">rs-1</code>. Currently there is only
          one instance, and the next task is to add more instances to
          the replica set.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="adding-replicaset-instances"></a>21.6.3 Adding Instances to a Replica Set</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249808768"></a><p>
        When you have created a replica set you can use the
        <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.addInstance()</code>
        operation to add an instance as a read-only secondary replica of
        the current primary of the replica set. Therefore, the primary
        of the replica set must be reachable and available during this
        operation. MySQL Replication is configured between the added
        instance and the primary, using an automatically created MySQL
        account with a random password. Once the instance is added to
        the replica set, the operation waits for the newly added
        instance to apply all pending transactions. This process is
        called distributed recovery, and MySQL Shell supports different
        methods which you configure with the
        <code class="literal">recoveryMethod</code> option.
      </p><p>
        MySQL Shell connects to the target instance using the same user
        name and password used to obtain the
        <code class="literal">ReplicaSet</code> handle object. All instances of
        the replica set are expected to have the same administrator
        account with the same grants and passwords. A custom
        administrator account with the required grants can be created
        while an instance is configured with
        <code class="literal">dba.configureReplicaSetInstance()</code>. See
        <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-replicaset-instances" title="Configuring InnoDB Replica Set Instances">Configuring InnoDB Replica Set Instances</a>.
      </p><p>
        When an instance is joining a replica set, distributed recovery
        is used in much the same way that it is in InnoDB cluster.
        This means that you can choose between MySQL Clone and
        incremental recovery. For more information, see
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-clone-deployment" title="21.2.5 Using MySQL Clone with InnoDB cluster">Section 21.2.5, “Using MySQL Clone with InnoDB cluster”</a>. This
        section covers the differences when using adding instances to a
        replica set.
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="add-instance-prerequisites"></a>Prerequisites</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444249798688"></a><p>
          For an instance to be able to join a replica set, the
          following prerequisites must be satisfied. They are
          automatically checked by
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.addInstance()</code>,
          and the operation fails if any issues are found.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              binary log and replication related options must have been
              at least validated and also possibly configured by
              <code class="literal">dba.configureReplicaSetInstance()</code>
</p></li></ul>
</div>
<p>
          If the selected recovery method is incremental:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              the transaction set on the instance being added must not
              contain transactions that do not exist on the primary
            </p></li><li class="listitem"><p>
              the transaction set on the instance being added must not
              be missing
            </p></li><li class="listitem"><p>
              transactions that have been purged from the binary log of
              the primary

              
</p></li></ul>
</div>
<p>
          If MySQL Clone is available on both the primary and the
          instance you want to add to the replica set, the prerequisites
          listed above can be overcome by using clone as the recovery
          method.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="add-instance-replicaset"></a>Adding Instances to a ReplicaSet</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249787232"></a><p>
          Once you have created a replica set and assigned it to a
          variable, use the
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.addInstance(<em class="replaceable"><code>instance</code></em>)</code>
          operation to add secondary instances to the replica set. You
          specify the instance as a URI-like connection string, see
          <a class="xref" href="programs.html#connecting-using-uri-or-key-value-pairs" title="4.2.5 Connecting to the Server Using URI-Like Strings or Key-Value Pairs">Section 4.2.5, “Connecting to the Server Using URI-Like Strings or Key-Value Pairs”</a>. The
          user you specify must have the privileges required and must be
          the same on all instances in the replica set, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#configuring-replicaset-instances" title="Configuring InnoDB Replica Set Instances">Configuring InnoDB Replica Set Instances</a>. If you
          want to check the operation but not actually make any changes,
          use the <code class="literal">dryRun</code> option. This shows what
          actions the MySQL Shell would take to add the instance to the
          replica set.
        </p><p>
          For example to add the instance at <code class="literal">rs-2</code>
          with user <code class="literal">rsadmin</code>, issue:
        </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>rs.addInstance('rsadmin@rs-2')</code></strong>

Adding instance to the replicaset...

* Performing validation checks

This instance reports its own address as rsadmin@rs-2
rsadmin@rs-2: Instance configuration is suitable.

* Checking async replication topology...

* Checking transaction state of the instance...

NOTE: The target instance 'rsadmin@rs-2' has not been pre-provisioned (GTID set
is empty). The Shell is unable to decide whether replication can completely
recover its state.  The safest and most convenient way to provision a new
instance is through automatic clone provisioning, which will completely
overwrite the state of 'rsadmin@rs-2' with a physical snapshot from an existing
replicaset member. To use this method by default, set the 'recoveryMethod'
option to 'clone'.

WARNING: It should be safe to rely on replication to incrementally recover the
state of the new instance if you are sure all updates ever executed in the
replicaset were done with GTIDs enabled, there are no purged transactions and
the new instance contains the same GTID set as the replicaset or a subset of it.
To use this method by default, set the 'recoveryMethod' option to 'incremental'.
Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone):
</pre><p>
          In this case we did not specify the recovery method, so the
          operation advises you on how to best proceed. In this example
          we choose the clone option because we do not have any existing
          transactions on the instance joining the replica set.
          Therefore there is no risk of deleting data from the joining
          instance.
        </p><pre class="programlisting">Please select a recovery method [C]lone/[I]ncremental recovery/[A]bort (default Clone): <strong class="userinput"><code>C</code></strong>
* Updating topology
Waiting for clone process of the new member to complete. Press ^C to abort the operation.
* Waiting for clone to finish...
NOTE: rsadmin@rs-2 is being cloned from rsadmin@rs-1
** Stage DROP DATA: Completed
** Clone Transfer  
FILE COPY  ############################################################  100%  Completed
PAGE COPY  ############################################################  100%  Completed
REDO COPY  ############################################################  100%  Completed
** Stage RECOVERY: \
NOTE: rsadmin@rs-2 is shutting down...

* Waiting for server restart... ready
* rsadmin@rs-2 has restarted, waiting for clone to finish...
* Clone process has finished: 59.63 MB transferred in about 1 second (~1.00 B/s)

** Configuring rsadmin@rs-2 to replicate from rsadmin@rs-1
** Waiting for new instance to synchronize with PRIMARY...

The instance 'rsadmin@rs-2' was added to the replicaset and is replicating from rsadmin@rs-1.
</pre><p>
          Assuming the instance is valid for InnoDB ReplicaSet usage,
          distributed recovery proceeds. In this case the newly joining
          instance uses MySQL Clone to copy all of the transactions it
          has not yet applied from the primary, then it joins the
          replica set as an online instance. To verify, use the
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.status()</code>
          operation:
        </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>rs.status()</code></strong>
{    
    "replicaSet": {
        "name": "example", 
        "primary": "rs-1:3306", 
        "status": "AVAILABLE", 
        "statusText": "All instances available.", 
        "topology": {
            "rs-1:3306": {
                "address": "rs-1:3306", 
                "instanceRole": "PRIMARY", 
                "mode": "R/W", 
                "status": "ONLINE"
            }, 
            "rs-2:3306": {
                "address": "rs-2:3306", 
                "instanceRole": "SECONDARY", 
                "mode": "R/O", 
                "replication": {
                    "applierStatus": "APPLIED_ALL", 
                    "applierThreadState": "Slave has read all relay log; waiting for more updates", 
                    "receiverStatus": "ON", 
                    "receiverThreadState": "Waiting for master to send event", 
                    "replicationLag": null
                }, 
                "status": "ONLINE"
            }
        }, 
        "type": "ASYNC"
    }
}
</pre><p>
          This output shows that the replica set named
          <code class="literal">example</code> now consists of two MySQL
          instances, and that the primary is <code class="literal">rs-1</code>.
          Currently there is one secondary instance at
          <code class="literal">rs-2</code>, which is a replica of the primary.
          The replica set is online, which means that the primary and
          secondary are in synchrony. At this point the replica set is
          ready to process transactions.
        </p><p>
          If you want to override the interactive MySQL Shell mode
          trying to choose the most suitable recovery method, use the
          <code class="literal">recoveryMethod</code> option to configure how the
          instance recovers the data required to be able to join the
          replica set. For more information, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-clone-deployment" title="21.2.5 Using MySQL Clone with InnoDB cluster">Section 21.2.5, “Using MySQL Clone with InnoDB cluster”</a>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="replicaset-adopting"></a>21.6.4 Adopting an Existing Replication Set Up</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249760928"></a><p>
        As an alternative to creating a new InnoDB ReplicaSet, you can
        also adopt an existing replication setup using the
        <code class="literal">adoptFromAR</code> option with
        <code class="literal">dba.createReplicaSet()</code>. The replication setup
        is scanned, and if it is compatible with the InnoDB ReplicaSet
        prerequisites, AdminAPI creates the necessary metadata. Once
        the replication setup has been adopted, you can only use
        AdminAPI to administer the InnoDB ReplicaSet.
      </p><p>
        To convert an existing replication setup to a
        InnoDB ReplicaSet connect to the primary, also referred to as
        the master. The replication topology is automatically scanned
        and validated, starting from the instance MySQL Shell's global
        session is connected to. The configuration of all instances is
        checked during adoption, to ensure they are compatible with
        InnoDB ReplicaSet usage. All replication channels must be
        active and their transaction sets as verified through GTID sets
        must be consistent. The data set of all instances are expected
        to be identical, but is not verified.

        

        All instances that are part of the topology are automatically
        added to the replica set. The only changes made by this
        operation to an adopted replica set are the creation of the
        metadata schema. Existing replication channels are not changed
        during adoption, although they could be changed during
        subsequent primary switch operations.
      </p><p>
        For example, to adopt a replication topology consisting of the
        MySQL server instances on <code class="literal">example1</code> and
        <code class="literal">example2</code> to an InnoDB ReplicaSet, connect
        to the primary at <code class="literal">example1</code> and issue:
      </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>rs = dba.createReplicaSet('testadopt', {'adoptFromAR':1})</code></strong>
A new replicaset with the topology visible from 'example1:3306' will be created.

* Scanning replication topology...
** Scanning state of instance example1:3306
** Scanning state of instance example2:3306

* Discovering async replication topology starting with example1:3306
Discovered topology:
- example1:3306: uuid=00371d66-3c45-11ea-804b-080027337932 read_only=no
- example2:3306: uuid=59e4f26e-3c3c-11ea-8b65-080027337932 read_only=no
    - replicates from example1:3306
	source="localhost:3310" channel= status=ON receiver=ON applier=ON

* Checking configuration of discovered instances...

This instance reports its own address as example1:3306
example1:3306: Instance configuration is suitable.

This instance reports its own address as example2:3306
example2:3306: Instance configuration is suitable.

* Checking discovered replication topology...
example1:3306 detected as the PRIMARY.
Replication state of example2:3306 is OK.

Validations completed successfully.

* Updating metadata...

ReplicaSet object successfully created for example1:3306.
Use rs.add_instance() to add more asynchronously replicated instances to
this replicaset and rs.status() to check its status.
</pre><p>
        Once the InnoDB ReplicaSet has been adopted, you can use it in
        the same way that you would use a replica set which was created
        from scratch. From this point you must administer the
        InnoDB ReplicaSet using only AdminAPI.
</p>
</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="working-with-replicasets"></a>21.6.5 Working with InnoDB ReplicaSet</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249746288"></a><p>
        You work with an InnoDB ReplicaSet in much the same way as you
        would work with an InnoDB cluster. For example as seen in
        <a class="xref" href="mysql-innodb-cluster-userguide.html#add-instance-replicaset" title="Adding Instances to a ReplicaSet">Adding Instances to a ReplicaSet</a>, you assign a
        <code class="literal">ReplicaSet</code> object to a variable and call
        operations that administer the replica set, such as
        <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.addInstance()</code>
        to add instances, which is the equivalent of
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.addInstance()</code>
        in InnoDB cluster. Thus, much of the documentation at
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-working-with-cluster" title="21.5 Working with InnoDB Cluster">Section 21.5, “Working with InnoDB Cluster”</a> also
        applies to InnoDB ReplicaSet. The following operations are
        supported by <code class="literal">ReplicaSet</code> objects:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            You get online help for <code class="literal">ReplicaSet</code>
            objects, and the AdminAPI, using <code class="literal">\help
            ReplicaSet</code> or
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.help()</code>
            and <code class="literal">\help dba</code> or
            <code class="literal">dba.help()</code>. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#admin-api" title="Using AdminAPI">Using AdminAPI</a>.
          </p></li><li class="listitem"><p>
            You can quickly check the name of a
            <code class="literal">ReplicaSet</code> object using either
            <code class="literal">name</code> or
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.getName()</code>.
            For example the following are equivalent:
          </p><pre class="programlisting">mysql-js&gt; <strong class="userinput"><code>rs.name</code></strong>
example
mysql-js&gt; <strong class="userinput"><code>rs.getName()</code></strong>
example
</pre></li><li class="listitem"><p>
            You check information about a replica set using the
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.status()</code>
            operation, which supports the <code class="literal">extended</code>
            option to get different levels of detail. For example:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: circle; "><li class="listitem"><p>
                the default for <code class="literal">extended</code> is 0, a
                regular level of details. Only basic information about
                the status of the instance and replication is included,
                in addition to non-default or unexpected replication
                settings and status.
              </p></li><li class="listitem"><p>
                setting <code class="literal">extended</code> to 1 includes
                Metadata Version, server UUID and the raw information
                used to derive the status of the instance, size of the
                applier queue, value of system variables that protect
                against unexpected writes and so on.
              </p></li><li class="listitem"><p>
                setting <code class="literal">extended</code> to 2 includes
                important replication related configuration settings,
                such as SSL, worker threads, replication delay and
                heartbeat delay.
</p></li></ul>
</div>
<p>
            See <a class="xref" href="mysql-innodb-cluster-userguide.html#check-innodb-cluster-status" title="Checking a cluster's Status with Cluster.status()">Checking a cluster's Status with
        <code class="literal"><em class="replaceable"><code>Cluster</code></em>.status()</code></a>.
          </p></li><li class="listitem"><p>
            You change the instances being used for a replica set using
            the
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.addInstance()</code>
            and
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.removeInstance()</code>
            operations. See <a class="xref" href="mysql-innodb-cluster-userguide.html#add-instance-replicaset" title="Adding Instances to a ReplicaSet">Adding Instances to a ReplicaSet</a>,
            and <a class="xref" href="mysql-innodb-cluster-userguide.html#remove-instances-from-innodb-cluster" title="Removing Instances from the InnoDB Cluster">Removing Instances from the InnoDB Cluster</a>.
          </p></li><li class="listitem"><p>
            In the event of an instance leaving the replica set, for
            example due to an unexpected halt, use the
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.rejoinInstance()</code>
            operation. See <a class="xref" href="mysql-innodb-cluster-userguide.html#rejoin-cluster" title="Rejoining a Cluster">Rejoining a Cluster</a>.
          </p></li><li class="listitem"><p>
            You work with the MySQL Router instances which have been
            bootstrapped against a replica set in exactly the same way
            as with InnoDB cluster. See
            <a class="xref" href="mysql-innodb-cluster-userguide.html#registered-routers" title="Working with a Cluster's Routers">Working with a Cluster's Routers</a> for information on
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.listRouters()</code>
            and
            <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.removeRouterMetadata()</code>.
            For specific information on using MySQL Router with
            InnoDB ReplicaSet see
            <a class="xref" href="mysql-innodb-cluster-userguide.html#replicasets-working-with-router" title="21.6.6 Using Replica Sets with MySQL Router">Section 21.6.6, “Using Replica Sets with MySQL Router”</a>.
</p></li></ul>
</div>
<p>
        For more information, see the linked InnoDB cluster sections.
      </p><p>
        The following operations are specific to InnoDB ReplicaSet and
        can only be called against a <code class="literal">ReplicaSet</code>
        object:
</p>
<div class="simplesect">

<div class="titlepage">
<div>

<div class="simple">
<h4 class="title"><a name="set-replicaset-primary"></a>Planned Changes of the Replica Set Primary</h4>
</div>
</div>
</div>
<a class="indexterm" name="idm46444249703264"></a><p>
          Use the
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.setPrimaryInstance()</code>
          operation to safely perform a change of the primary of a
          replica set to another instance. The current primary is
          demoted to a secondary and made read-only, while the promoted
          instance becomes the new primary and is made read-write. All
          other secondary instances are updated to replicate from the
          new primary. MySQL Router instances which have been bootstrapped
          against the replica set automatically start redirecting
          read-write clients to the new primary.
        </p><p>
          For a safe change of the primary to be possible, all replica
          set instances must be reachable by MySQL Shell and have
          consistent <code class="literal">GTID_EXECUTED</code> sets. If the
          primary is not available, and there is no way to restore it, a
          forced failover might be the only option instead, see
          <a class="xref" href="mysql-innodb-cluster-userguide.html#force-replicaset-primary" title="Forcing the Primary Instance in a Replica Set">Forcing the Primary Instance in a Replica Set</a>.
        </p><p>
          During a change of primary, the promoted instance is
          synchronized with the old primary, ensuring that all
          transactions present on the primary are applied before the
          topology change is committed. If this synchronization step
          takes too long or is not possible on any of the secondary
          instances, the operation is aborted. In such a situation,
          these problematic secondary instances must be either repaired
          or removed from the replica set for the fail over to be
          possible.
</p>
</div>
<div class="simplesect">
<div class="titlepage">
<div>
<div class="simple">
<h4 class="title"><a name="force-replicaset-primary"></a>Forcing the Primary Instance in a Replica Set</h4>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249695344"></a><p>
          Unlike InnoDB cluster, which supports automatic failover in
          the event of an unexpected failure of the primary,
          InnoDB ReplicaSet does not have automatic failure detection
          or a consensus based protocol such as that provided by Group
          Replication. If the primary is not available, a manual
          failover is required. An InnoDB ReplicaSet which has lost
          its primary is effectively read-only, and for any write
          changes to be possible a new primary must be chosen. In the
          event that you cannot connect to the primary, and you cannot
          use
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.setPrimaryInstance()</code>
          to safely perform a switchover to a new primary as described
          at <a class="xref" href="mysql-innodb-cluster-userguide.html#set-replicaset-primary" title="Planned Changes of the Replica Set Primary">Planned Changes of the Replica Set Primary</a>, use the
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.forcePrimaryInstance()</code>
          operation to perform a forced failover of the primary. This is
          a last resort operation that must only be used in a disaster
          type scenario where the current primary is unavailable and
          cannot be restored in any way.
</p>
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;">

<div class="admon-title">
Warning
</div>
<p>
            A forced failover is a potentially destructive action and
            must be used with caution.
</p>
</div>
<p>
          If a target instance is not given (or is null), the most
          up-to-date instance is automatically selected and promoted to
          be the new primary. If a target instance is provided, it is
          promoted to a primary, while other reachable secondary
          instances are switched to replicate from the new primary. The
          target instance must have the most up-to-date
          <code class="literal">GTID_EXECUTED</code> set among reachable
          instances, otherwise the operation fails.
        </p><p>
          A failover is different from a planned primary change because
          it promotes a secondary instance without synchronizing with or
          updating the old primary. That has the following major
          consequences:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
              Any transactions that had not yet been applied by a
              secondary primary to a secondary at the time the old
              primary failed are lost.
            </p></li><li class="listitem"><p>
              If the old primary is actually still running and
              processing transactions, there is a split-brain and the
              datasets of the old and new primaries diverge.
</p></li></ul>
</div>
<p>
          If the last known primary is still reachable, the
          <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.forcePrimary()</code>
          operation fails, to reduce the risk of split-brain situations.
          But it is the administrator's responsibility to ensure that
          the old primary it is not reachable by the other instances to
          prevent or minimize such scenarios.
        </p><p>
          After a forced failover, the old primary is considered invalid
          by the new primary and can no longer be part of the replica
          set. If at a later date you find a way to recover the
          instance, it must be removed from the replica set and re-added
          as a new instance. If there were any secondary instances that
          could not be switched to the new primary during the failover,
          they are also considered invalid.
        </p><p>
          Data loss is possible after a failover, because the old
          primary might have had transactions that were not yet
          replicated to the secondary being promoted. Moreover, if the
          instance that was presumed to have failed is still able to
          process transactions, for example because the network where it
          is located is still functioning but unreachable from
          MySQL Shell, it continues diverging from the promoted
          instances. Recovering once transaction sets on instances have
          diverged requires manual intervention and could not be
          possible in some situations, even if the failed instances can
          be recovered. In many cases, the fastest and simplest way to
          recover from a disaster that required a forced failover is by
          discarding such diverged transactions and re-provisioning a
          new instance from the newly promoted primary.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="replicasets-working-with-router"></a>21.6.6 Using Replica Sets with MySQL Router</h3>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249678928"></a><p>
        You can use MySQL Router 8.0.19 and later to bootstrap against a
        replica set, in the same way that InnoDB cluster can be
        bootstrapped. See
        <a class="xref" href="mysql-innodb-cluster-userguide.html#mysql-innodb-cluster-using-router" title="21.4 Using MySQL Router with InnoDB Cluster">Section 21.4, “Using MySQL Router with InnoDB Cluster”</a>. The only
        difference in the generated MySQL Router configuration file is the
        addition of the <a class="ulink" href="https://dev.mysql.com/doc/mysql-router/8.0/en/mysql-router-conf-options.html#option_mysqlrouter_cluster_type" target="_top"><code class="option">cluster_type</code></a>
        option. When MySQL Router is bootstrapped against a replica set, the
        generated configuration file includes:
      </p><pre class="programlisting">cluster_type=rs</pre><p>
        When you use MySQL Router with a replica set, be aware that:
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
            The read-write port of MySQL Router directs client connections
            to the primary instance of the replica set
          </p></li><li class="listitem"><p>
            The read-only port of MySQL Router direct client connections to
            a secondary instance of the replica set, although it could
            also direct them to the primary
          </p></li><li class="listitem"><p>
            MySQL Router obtains information about the replica set's
            topology from the primary instance
          </p></li><li class="listitem"><p>
            MySQL Router automatically recovers when the primary instance
            becomes unavailable and a different instance is promoted
</p></li></ul>
</div>
<p>
        You work with the MySQL Router instances which have been
        bootstrapped against a replica set in exactly the same way as
        with InnoDB cluster. See <a class="xref" href="mysql-innodb-cluster-userguide.html#registered-routers" title="Working with a Cluster's Routers">Working with a Cluster's Routers</a>
        for information on
        <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.listRouters()</code>
        and
        <code class="literal"><em class="replaceable"><code>ReplicaSet</code></em>.removeRouterMetadata()</code>.
</p>
</div>

</div>
<div class="section">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="mysql-innodb-cluster-limitations"></a>21.7 Known Limitations</h2>

</div>

</div>

</div>
<a class="indexterm" name="idm46444249664672"></a><p>
      This section describes the known limitations of InnoDB cluster.
      As InnoDB cluster uses Group Replication, you should also be
      aware of its limitations, see
      <a class="xref" href="group-replication.html#group-replication-limitations" title="18.9.2 Group Replication Limitations">Section 18.9.2, “Group Replication Limitations”</a>.
</p>
<div class="itemizedlist">
<ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
          

          If a session type is not specified when creating the global
          session, MySQL Shell provides automatic protocol detection
          which attempts to first create a NodeSession and if that fails
          it tries to create a ClassicSession. With an InnoDB cluster
          that consists of three server instances, where there is one
          read-write port and two read-only ports, this can cause
          MySQL Shell to only connect to one of the read-only
          instances. Therefore it is recommended to always specify the
          session type when creating the global session.
        </p></li><li class="listitem"><p>
          

          When adding non-sandbox server instances (instances which you
          have configured manually rather than using
          <code class="literal">dba.deploySandboxInstance()</code>)

          

          to a cluster, MySQL Shell is not able to persist any
          configuration changes in the instance's configuration file.
          This leads to one or both of the following scenarios:
</p>
<div class="orderedlist">
<ol class="orderedlist" type="1"><li class="listitem"><p>
              The Group Replication configuration is not persisted in
              the instance's configuration file and upon restart the
              instance does not rejoin the cluster.
            </p></li><li class="listitem"><p>
              The instance is not valid for cluster usage. Although the
              instance can be verified with
              <code class="literal">dba.checkInstanceConfiguration()</code>, and
              MySQL Shell makes the required configuration changes in
              order to make the instance ready for cluster usage, those
              changes are not persisted in the configuration file and so
              are lost once a restart happens.
</p></li></ol>
</div>
<p>
          If only <code class="literal">a</code> happens, the instance does not
          rejoin the cluster after a restart.
        </p><p>
          If <code class="literal">b</code> also happens, and you observe that the
          instance did not rejoin the cluster after a restart, you
          cannot use the recommended
          <code class="literal">dba.rebootClusterFromCompleteOutage()</code> in
          this situation to get the cluster back online. This is because
          the instance loses any configuration changes made by
          MySQL Shell, and because they were not persisted, the
          instance reverts to the previous state before being configured
          for the cluster. This causes Group Replication to stop
          responding, and eventually the command times out.
        </p><p>
          To avoid this problem it is strongly recommended to use
          <code class="literal">dba.configureInstance()</code> before adding
          instances to a cluster in order to persist the configuration
          changes.
        </p></li><li class="listitem"><p>
          



          

          The use of the
          <a class="link" href="server-administration.html#option_mysqld_defaults-extra-file"><code class="option">--defaults-extra-file</code></a> option to
          specify an option file is not supported by InnoDB cluster
          server instances. InnoDB cluster only supports a single
          option file on instances and no extra option files are
          supported. Therefore for any operation working with the
          instance's option file the main one should be specified. If
          you want to use multiple option files you have to configure
          the files manually and make sure they are updated correctly
          considering the precedence rules of the use of multiple option
          files and ensuring that the desired settings are not
          incorrectly overwritten by options in an extra unrecognized
          option file.
        </p></li><li class="listitem"><p>
          

          Attempting to use instances with a host name that resolves to
          an IP address which does not match a real network interface
          fails with an error that <span class="errortext">This instance reports its
          own address as <em class="replaceable"><code>the
          hostname</code></em></span>. This is not supported by
          the Group Replication communication layer. On Debian based
          instances this means instances cannot use addresses such as
          <code class="literal">user@localhost</code> because localhost resolves
          to a non-existent IP (such as 127.0.1.1). This impacts on
          using a sandbox deployment, which usually uses local instances
          on a single machine.
        </p><p>
          A workaround is to configure the
          <code class="literal">report_host</code> system variable on each
          instance to use the actual IP address of your machine.
          Retrieve the IP of your machine and add
          <code class="literal">report_host=<em class="replaceable"><code>IP of your
          machine</code></em></code> to the
          <code class="filename">my.cnf</code> file of each instance. You need to
          ensure the instances are then restarted to make the change.
</p></li></ul>
</div>

</div>

</div>
<div class="copyright-footer">

</div>
<div class="navfooter">
<hr>
<table width="100%" summary="Navigation footer">
<tr>
<td width="40%" align="left"><a accesskey="p" href="document-store.html">Prev</a></td>
<td width="20%" align="center"><a accesskey="u" href="">Up</a></td>
<td width="40%" align="right"> <a accesskey="n" href="mysql-cluster.html">Next</a></td>
</tr>
<tr>
<td width="40%" align="left" valign="top">Chapter 20 Using MySQL as a Document Store</td>
<td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td>
<td width="40%" align="right" valign="top">Chapter 22 MySQL NDB Cluster 8.0</td>
</tr>
</table>
</div>
</body>
</html>
